Клиентская оптимизация
Клиентская оптимизация — это набор методов для ускорения загрузки, отображения и работы сайтов в браузерах.
Теория
Начинающий специалист найдет понятное изложение основ клиентской оптимизации в книгах «Реактивные веб-сайты» и «Разгони свой сайт».
Недавно досмотрел трехчасовой доклад Ильи Григорика, специалиста Гугла, о технических особенностях работы сетей и браузеров и о следствиях для клиентской оптимизации (первая часть и вторая часть). Многое было знакомым. Тем не менее, послушал не без интереса.
Среди прочего речь шла о том, что на скорость загрузки и отображения сайтов влияет не только ширина канала, но и задержки времени (latency; измеряется утилитой ping). При этом ситуация в мобильном и десктопном вебе существенно различается. Хотя с развитием мобильных сетей ширина каналов растет, с задержками по-прежнему всё плохо.
Действительно новым для меня был совет о вреде буферизации. Желательно как можно быстрее отдать браузеру хотя бы часть страницы, а потом уже производить <head>
и шапку страницы. Браузер распознает обращение ко внешним стилям и начнет загружать css-файлы, не дожидаясь загрузки остального html-кода.
В своем движке S2 я делал ровно противоположную вещь: специально перехватывал содержимое страницы для вычисления размера ответа (заголовок Content-length
), для вычисления хеша ETag и, наконец, для
Ранняя отправка части ответа лишает нас этих плюшек. И если вы задумываетесь о такой оптимизации, то легко пожертвуете условными GET-запросами и сжатием (которое на больших нагрузках скорее всего окажется вредным). Что касается Content-length
, то без этого заголовка в HTTP 1.0 не работал механизм
Напомню, что
Отсутствие буферизации лишает еще одной полезной возможности отправлять заголовки в процессе обработки запроса. Например, если в базе данных не нашлось содержимого, соответствующего запрошенному URL, то уже нельзя отправить заголовок о 404-й ошибке. Или сделать перенаправление 301/302.
В общем, следовать совету о ранней отправке непросто. И дело не только в настройке программного обеспечения, которое с радостью буферизирует всё подряд. Дело в том, что не всегда можно выделить неизменную часть страницы со ссылками на стили, не выполняя остальной работы по построению страницы. Я решил, что в S2 такой оптимизации не будет. Она сильно ограничила бы гибкость. Да и выигрыш получается небольшим при времени сборки страницы в несколько десятков миллисекунд.
Практика
После просмотра теоретического материала я, как любитель оптимизировать, должен был посмотреть свежим взглядом на свои сайты. Каково же было мое удивление, когда я обнаружил на сайте движка обращение к Google Analytics, хотя никогда ее не устанавливал! Причина оказалась неожиданной.
Как известно, браузеры еще не научились показывать видео так же легко и просто, как картинки. Когда я размещал на сайте движка видеоинструкции, выяснилось, что видеохостинги пережимают файлы и изменяют размер кадра, чем портят записанную с экрана картинку. Тогда я воспользовался библиотекой video.js. Она показывает ролики через HTML 5 в современных браузерах и во флеш-плеере в устаревших.
Для простоты я не стал загружать файлы на свой сервер и подключил библиотеку из CDN. Это было разумно и с точки зрения оптимизации: CDN отдавал сжатую версию, а на моем сервере gzip-сжатие статических файлов не было настроено. Как говорится, сделал и забыл. Но бесплатный сыр бывает только в мышеловке. И в качестве «платы» авторы video.js со временем включили в CDN-версию вызов Google Analytics. Вот еще одна причина не доверять свои сайты чужим сервисам.
Загрузил библиотеку на сервер и начал решать вопрос с gzip-сжатием. Как и любой нормальный веб-сервер, nginx способен сжимать файлы на лету. Но это создает дополнительную нагрузку на сервер, ведь ему приходится делать одну и ту же работу при каждом запросе к файлам. Другую интересную возможность предоставляет модуль gzip static. Этот модуль отдает вместо запрашиваемых файлов заранее подготовленные сжатые версии этих файлов с расширением .gz
. Их удобно создавать во время развертывания сайта или по расписанию. Например, команда gzip -cn6 script.js > script.js.gz
рядом с файлом script.js
создаст файл script.js.gz
.
Когда-то давно nginx в стандартных пакетах Debian был скомпилирован без модуля gzip static. В текущей же версии, Debian 7, ситуация изменилась, и мне оставалось добавить несколько строк к конфигурации nginx. В результате 50-килобайтный скрипт video.js сжимается до 16 килобайт.
В заключение обсудим вопрос об этих 50 килобайтах ради отображения видео. 50 килобайт — много это или мало? Сегодня многие скажут «мало», обвешивая сайт библиотеками и фреймворками на сотни килобайт. Я противник такого подхода. Моя правота подтверждается каждый раз, когда кто-то пытается открывать сайты на медленном интернете. Другое дело — сжатая в три раза версия. Загрузка 16 килобайт скриптов для кроссбраузерного отображения видео вполне допустима.
Оставьте свой комментарий