Клиентская оптимизация оперирует двумя основными принципами: меньше данных и меньше соединений. Но именно эти принципы помогают уменьшить нагрузку на сам сервер. Давайте посмотрим, как это происходит и как перенести часть серверной нагрузки на клиентский браузер.
Кеширование во главу угла. Сервер может управлять состоянием кеша клиентского браузера, во-первых, через заголовок Cache-Control
(и его атрибуты max-age
, pre-check
, post-check
), который может указывать на промежуток времени, в течение которого соответствующий файл следует хранить на диске и не запрашивать с сервера. Рекомендуется для всех статических файлов выставлять максимальное время жизни кеша и форсировать его обновление у пользователя через изменение URL ресурса (с помощью RewriteRule
либо GET-параметра).
Во-вторых, состоянием клиентского кеша можно управлять через заголовки ETag
и Last-Modified
, которые ставят в соответствие каждому файлу уникальный идентификатор, изменяющийся при изменении файла, своеобразная цифровая подпись или хеш. При этом серверу не нужно пересылать файл заново, а лишь ответить кодом 304 на запрос браузера, если файл не изменился с момента последнего запроса. При этом сам файл не пересылается, соединение (и сокет) освобождается быстрее, и ресурса сервера также экономятся.
Меньше запросов — легче серверу. Объединение файлов никто не отменял. Чтобы не заставлять сервер обмениваться с браузером заголовками для передачи, например, нескольких таблиц стилей гораздо экономичнее будет их объединить в одну. При этом браузер быстрее получит всю необходимую информацию и быстрее освободит такой важный ресурс как соединение.
Наряду с объединением текстовых файлов не стоит пренебрегать и объединением картинок. Если учитывать, что современные браузеры могут устанавливать несколько десятков одновременных соединений с сервером для получения статических файлов (и 80% из них — это именно картинки), то экономия от использования CSS Sprites или Image Map рассчитывается очень просто. В некоторых случаях удается уменьшить число соединений браузера с сервером для загрузки одной HTML-страницы в 8–10 раз.
Архивировать и кешировать на сервере. Как показали проведенные исследования gzip-сжатия текстового файла «на лету» в 95–98% случаев позволяет сократить время на передачу файла браузеру. Если хранить архивированные копии файлов сервере (в памяти proxy-сервере или просто на диске), то соединение в общем случае удается освободить в 3–4 раза быстрее.
В случае высоконагруженных серверов с динамическими HTML-файлами gzip также может применим. Здесь стоит ориентироваться на минимальную степень сжатия, ибо процессорные издержки при это растут линейно, а размер уменьшается лишь логарифмически.
Следующие моменты стоит рассматривать как спорные: они могут как ускорить загрузку ваших сайтов, так и замедлить ее или слишком осложнить процесс разработки.
Создание нескольких зеркал для выдачи статических файлов обычно помогает ускорить загрузку страницы в браузере, но каково при этом приходится серверу? В общем случае, если общее число файлов на странице не превосходит 10, то зеркала применять нецелесообразно. При 10-20 файлах стоит ограничиться лишь одним зеркалом, и лишь если файлов становится несколько десятков, то стоит думать о 2–3 зеркалах.
Однако, при существовании большого количества файлов (например, картинок) разумнее будет их объединять — это поможет и серверу и клиенту.
Технология кроссбраузерного data:URL
позволяет использовать один CSS-файл и для стилевых правил, и для небольших фоновых картинок. Это позволяет избежать использования CSS Sprites и многочисленных обращений для загрузки мелких фоновых изображений.
Однако, данный подход связан с некоторыми технологическими сложностями (необходима дополнительная обработка файлов перед их публикацией на рабочем сервере) и не позволяет осуществлять кеширование отдельных компонентов. В принципе, то же самое можно сказать и о включении CSS-/JS-файлов в HTML-страницу. Решение о таких мерах должно приниматься, исходя из индивидуальных особенностей проекта.
Cookie передаются при каждом запросе браузера на сервер. Иногда их размер может быть весьма значительным и даже превосходить полезный объем информации. К тому же, большое количество значений в заголовке Cookie несет дополнительную нагрузку на серверную логику — ведь обычно все их нужно проанализировать и переслать обратно браузеру.
Одним из наиболее распространенных вариантов является выделение статических файлов на отдельное зеркало, на которое не передаются Cookie. Однако, этот подход не позволяет, например, показывать изображения только авторизованным пользователям. Отправка пользователю только необходимых cookie также сопряжена с логическими ошибками — нужно ведь послать определенные cookie всем нужным пользователям и не послать всем ненужным.
За счет объединения файлов и настройки агрессивного кеширования возможно уменьшение числа первоначальных запросов к серверу в несколько раз, и сведение повторных запросов всего к 1–2 (если все остальные десятки файлов браузер будет брать из собственного кеша). Это позволит значительно сократить число активных соединений в секунду.
Архивирование также помогает сократить нагрузку на сервер, однако, его нужно использовать более аккуратно, чтобы не навредить слишком большой степенью сжатия или архивированием не тех типов файлов (например, JPEG).
Есть также ряд других методов (параллельные загрузки, все-в-одном, cookie и т.д.), которые могут повлиять на серверную нагрузку. Однако, и все нужно использовать с крайней осторожностью, и большого снижения нагрузки за их счет добиться нельзя.
Спасибо за внимание, буду рад ответить на ваши вопросы.