Статьи

Перевод: Николай Мациевский aka sunnybear
Опубликована: 17 августа 2007

Как JavaScript тормозит Веб (и что с этим делать)?

Примечание: ниже перевод статьи "How JavaScript is Slowing Down the Web (And What To Do About It)", посвященной, в основном, работе с виджетами: характерные проблемы и методы их решения.

Одна строка JavаScript является основой большинства текущих технологий, которые используют авторы блогов. Виджеты, средства (фото-/видео-)обмена, отслеживание посетителей, рекламные объявления. Во многих случаях единственная строка JavaScript — это все, что нужно автору, чтобы добавить в своей блог что-то новенькое. Проблемы начинаются тогда, когда много-много этих самых строчек собирается вместе...

В физике это явление хорошо известно под термином нелинейность (non-linearity, на самом деле, это целый раздел физики, сюда относят массу разнородных явлений, объединенных одним общим свойством): когда множество разнородных вещей приходит в взаимодействие друг с другом, результат крайне тяжело предсказать. Программное обеспечение, на самом деле, ничем не отличается: если свести воедино множество компонентов, вы не сможете с уверенностью сказать, что же получится на самом деле. Это происходит из-за того, что компоненты, спроектированные для одиночной, независимой работы, начинают, буквально говоря, сражаться за имеющиеся ресурсы: реальное пространство (real estate space) и внимание людей. В результате этой войны страдают все: читатели, авторы и сами сервисы. Все оказываются в проигрыше.

В этой статье мы попытаемся рассмотреть, почему страницы разваливаются из-за большого количества «отдельных строчек кода», и как же с этим бороться.

Блогеры — жертвы своей наивности

Виджеты — это новые и неизведанные кусочки кода, за которыми будущее. Блогеры любят подчеркивать собственную индивидуальность и делать содержание своих блогов более уникальным. Именно поэтому авторы так стремятся поставить себе все новые и новые виджеты: del.icio.us, Flickr, Twitter, AddThis, Sphere — они все достаточно функциональны, и на них существует большой спрос.

Twitter widget

Виджеты предельны просты в установке, если вы хорошо знакомы с HTML и вашей платформой для блога. Все, что требуется, — это вставить HTML код для виджета туда, где вы хотите, чтобы он отобразился. Иногда его нужно вставить в тег head, но это абсолютно не сложно. Итак, имея даже минимальные технические познания, вы сможете это сделать либо для этой цели можно использовать платформу, наподобие Widgetbox, чтобы автоматизировать процесс.

Установка виджетов не представляет никаких сложностей, и пользователи устанавливают их один за другим в своих блогах — и вот тогда начинаются проблемы: как результат, блоги грузятся дольше.

Не все виджеты одинаково полезны

Сейчас существует две основные технологии для подключения виджетов: Flash и JavaScript. У виджетов на Flash'е одни трудности: большой размер файлов, невозможность изменить размер картинки, невозможность взаимодействия с DOM. Однако, это еще полбеды по сравнению с виджетами на JavaScript.

Самое смешное в том, что JavaScript задумывался и проектировался как легкий язык программирования для поддержки минимального взаимодействия и быстрых манипуляций с HTML на стороне клиента (пользовательского агента). Однако, во многом благодаря замысловатости пути развития этой технологии, JavaScript оказался (основным) языком программирования для веба. Сегодня JavaScript используется во многих передовых проектах: начиная с технологии AJAX и заканчивая виджетами. Однако, не без подводных камней. Давайте их рассмотрим...

Что браузеры делают с JavaScript?

Наверное, одним из наиболее шокирующих фактов для любого искушеннего специалиста является то, что JavaScript выполняется в один поток (далее все же делается небольшое отступление про timeout'ы, ведь они позволяют запускать несколько процессов если не параллельно, то хотя бы «псевдо-параллельно»). Это означает, что работа JavaScript-интерпретатора в браузере идет строго последовательно, никак не параллельно (за исключением вызовов AJAX). В тот момент, когда кусочек JavaScript загружается или исполняется, все остальное ждет в очереди.

Обработка браузерами JavaScript

Это означает, что отдельный JavaScript-скрипт способен несколько замедлить загрузку целого блога. И это повседневная реальность всей блогосферы (миллиарды часов машинного времени, истраченного на исполнение JavaScript; миллионы расстроенных блогеров; сотни тысяч долларов упущенной прибыли). И где же выход?

Итак, как сделать JavaScript-виджеты лучше и быстрее?

К сожалению, никакого универсального решения для этой проблемы нет: нет такого уникального приема, который бы мог разом решить ее. Однако, есть ряд действий, которые способны если не решить проблему окончательно, то заметно снизить ее остроту, и позволить частично избавиться от «нелинейных» эффектов. Ниже приводится их список, с которым рекомендуется ознакомиться всем производителям виджетов:

  1. Делайте загрузку JavaScript «отложенной»

    Одной из наиболее частых проблем из рассматриваемого комлекса является прямое исполнение JavaScript по ходу загрузки страницы, хотя этого можно и избежать. Если код скрипта не изменяет содержимое страницы (DOM) при загрузке, то выполнение этого кода может быть отложено до полной загрузки страницы. Таки образом, сначала появится содержание страницы, а потом уже будут выполняться все отложенные скрипты. К несчастью, это поддерживается не всеми браузерами. Подробнее про атрибут defer у тега <script>.

  2. Уменьшайте объем кода, который должен выполниться при полной загрузке страницы (при событии window.onload)

    Все, что исполняется после загрузки страницы, увеличивает время этой загрузки. Чем меньше кода будет выполнено, тем лучше. Другим важным моментом является отсечение зависимостей для загрузки конкретной страницы (когда загрузка зависит от ряда внешних загрузок или вызовов). Это большая проблема, т.к. может повлечь «подвисший» вызов скрипта. В любом случае, JavaScript код, который исполняется несколько секунд, является узким местом (bottleneck) при загрузке страницы. Используя разбиение выполнения кода на отдельные независимые части при помощи задержек (timeouts) можно частично решить эту проблему, хотя это и довольно дорогой («болезненный») путь. Также в этом случае может помочь использование «ненавязчивого» (unobtrustive) JavaScript

  3. Используйте балансировщик нагрузки при помощи различных URL для подгружаемого файла JavaScript

    Сейчас большинство скриптов использует единственный URL в качестве источника основного файла, например: www.mycoolwidget.com. Это немасштабируемое решение. Чем дальше распространяется виджет, тем больше нагрузка на сервер с исходным кодом, и число параллельных запросов на один и тот же сервер может быть достаточно большим. Лучше всего выдавать пользователям различные URL'ы, например: server1.mycoolwidget.com, server2.mycoolwidget.com и т.д. Пусть даже изначально они будут указывать на один и тот же IP адрес (физическую машину), однако, в будущем это позволит разделить трафик и нагрузку.

  4. Используйте стандартные библиотеки

    Пожалуй, хуже всего то, что авторы JavaScript кода каждый раз изобретают велосипед, хотя это и чревато большим количеством ошибок. По сравнению с Java (в которой присутствует набор стандартных библиотек), в JavaScript нет ничего, похожего на стандарт, но, по-видимому, довольно эффективно будет использовать такие разрабатываемые библиотеки, как prototype. Они написаны довольно опытными людьми, которые уже наступили не один раз на все возможные грабли, поэтому им можно доверять. В любом случае, использовать их наработки может оказаться очень полезным. Предполагается, то для уменьшения кода виджетов он подгружает стандартную библиотеку, ту же prototype, или проверяет, загружена ли она. Чем больше будет виджетов, использующих какой-то стандарт, тем меньше внешнего кода придется загружать посетителям страниц.

  5. «Семь раз отмерь, один раз отрежь»

    Предполагайте наличие других JavaScript файлов, которые могут загружаться на сайте автора блога, это очень вероятно. Рассматривая себя частью большой системы, разработчики могут избежать ряда проблем, которые могут возникнуть при конфликте их разработок с чужими (виджетами), и гарантировать доступность своих приложений у каждого отдельного пользователя.

Куда катится мир?

Хотя и (продвинутое) знание JavaScript в вебе и является плюсом для авторов, но разработчикам виджетов тоже есть над чем поразмыслить. Вы просто не сможете предположить, где и как ваш виджет будут использоваться, что еще будет установлено (на конкретной веб-странице). Без этой информации, отладка и отшлифовка скриптов может быть весьма затруднительной. Но в результате от этого страдают как сами авторы блогов, так и их читатели. Что же делать в таком случае?

Если мы обратимся к сообществу Java программистов, то можно обнаружить, что эта проблема уже давно у них решена. Апплеты, сервлеты и даже такая страшная вещь, как Enterprise Java Beans, на самом деле, имеют не так много идейных отличий от виджетов. Основная отличительная особенность заключается в использовании имеющегося framework'а (container).

Под framework'ом подразумевается, в первую очередь, окружение сервера, которое обеспечивает доставку данных до пользователя и клиент-серверное взаимодействие. На нем лежит загрузка, выгрузка, обратные вызовы (callbacks), клики, сообщения и все то, с чем технари так любят возиться, но что заставляет всех не-технических пользователей содрогнуться от ужаса. Иными словами, нужен общедоступный framework для JavaScript — ведь именно он вносит порядок в этот хаос компонентов и разработок.

Небольшой комментарий: сейчас W3C разрабатывает стандарт разработки виджетов. 5 июля опубликована черновая версия. Подробнее можно посмотреть здесь.

Читать дальше

Все комментарии (habrahabr.ru)