Создание и сопровождение сайтов

Блог. Yii. Javascript в Yii. Часть 1. Теория.

Поиск

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

  Итак. Сейчас практически не один сайт не обходится без java-скриптов и этот "язык" становится всё более популярным. Появилась и стремительно развивается серверная реализация языка - node.js. Отличительная особенность серверной реализации - возможность поддержания огромного количества одновременных подключений, что позволяет реализовать на нём вещи, порою трудновыполнимые на языках типа PHP.

  Особую популярность java-скриптам принесли различные фреймворки (jQuery, mootools, extJS и др.) и плагины к ним, которые позволяют с минимальными усилиями содавать очень красивые вещи. Тут и всевозможные "карусельки" для фотографий, и красивые загрузчики файлов. Тысячи всевозможных красявостей. И для установки не надо быть каким-то особым программистом - всё делается, как правило, очень просто.

  Но "великая власть требует великой ответственности" - множество различных элементов значительно утяжеляет страницу, увеличивая время её загрузки (в том числе и на мобильные устройства), увеличивает время рендеринга страницы (рендеринг страницы - это когда страница уже загружена, и браузер начинает её отрисовывать на экране).

  Рассмотрим подробнее эти процессы.

  Браузер посылает запрос на сервер, сервер возвращает код страницы. Тут всё просто и понятно.
Браузер начинает разбор полученной страницы. И появляются первые интересности - помимо самой страницы, нам, оказывается, необходимо еще загрузить стили, иконки, картинки, скрипты.. Например, при загрузке страницы Википедии о браузерах выполняется порядка 30 запросов: screenshot11

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

  Именно поэтому любое объявление стилей находится в секции <head>. Браузер при разборе документа находит эти стили первыми и начинает загружать их. И только потом должно идти всё остальное.

  Получаем первое правило: если у вас несколько файлов стилей и все они подключаются на странице - лучше их объеденить в один. Даже если файлы маленькие - любой запрос на сервер отнимает время: screenshot12 
(файл размером всего 114 байт, а на получение его потратили 60 миллисекунд. А будет таких файлов несколько десятков?). 

  Со скриптами дело обстоит интереснее (я пока говорю о внешних подключаемых файлах). Тэг <script> может размещаться как в <head>, так и в <body>. То есть, практически в любом месте документа. И если мы достаточно большой js-файл будем подключать еще до подключения стилей - мы может значительно увеличить время, необходимое браузеру для начала отображения документа.

  Поэтому, правило второе: все скрипты стараемся подключать в конце документа, перед </body>. Первостепенная цель - показать страницу, а "рюшечки" скриптовые могут и чуть подождать. Если файлов js много - стараемся их объеденить. Не обязательно в один, но сократить их число.

  Есть "уловки", позволяющие обходить ограничение в соединениях к одному серверу - это использовать несколько различных адресов и CDN.
Можно создать отдельный поддомен, с которого загружать стили, скрипты или картинки. Но это не панацея - делать надо с умом (общее количество подключений к другим серверам в браузерах тоже ограничено). Поэтому таким способом стараемся грузить только действительно необходимые вещи.

CDN - Content Delivery Network - "файлохранилища" крупных компаний (Гугль, Яндекс и др.). В основном доступны различные js-фреймворки. Плюс при запросе файла из CDN велика вероятность, что пользователь такой файл уже запрашивал и он лежит в кэше браузера.

  Еще одна из "уловок" - это "ленивая загрузка" - lazy load. Наиболее наглядно это видно на примере ленты из "ВКонтакте". Сначала загружается только часть информации, необходимой для первоначального отображения. А уже затем, если пользователь начинает листать страницу, постепенно подгружается еще. И тому подобные вариации.

  С загрузкой разобрались.
  Рассмотрим, в кратце, рендеринг страницы.
Скрипты на странице, чаще всего, выполняют либо в момент рендеринга, либо после его завершения. Так вот, js - язык последовательный. И если какой-то тяжелый код начинает выполняться во время рендеринга - это может тормозить сам рендеринг и откладывает выполнение остальных скриптов.

  Правило третье: я стараюсь любой js-код писать в конце страницы и выполнять его только после завершения рендеринга страницы - $(document).ready(function(){}) в jQuery.

  Еще на процесс рендеринга могут сильно влиять стили - если там есть какие-то сложные или медленные селекторы. Иногда это бывает заметно на сайтах со сложной структурой.


  Я не касался вопроса с кэшированием. Но сейчас этот вопрос теряет актуальность - зачастую каждый день просматривается такое количество объемной информации, что кэш браузера может терять свою актуальность через пару часов.