Оптимизация времени загрузки сайта
Оптимизация времени загрузки сайта: проблемы и решения
Сегодня речь пойдет о способах ускорения загрузки сайта. О методах увеличения эффективности сайта как инструмента продаж или оказания услуг, как существенной имиджевой составляющей бренда или просто личного блога.
Основные технологические направления по уменьшению времени загрузки веб-страниц:
- Уменьшение объема данных: большое число методов по минимизации и архивированию.
- Уменьшение числа запросов: основная технология — CSS Sprites.
- Кеширование.
- Параллельные загрузки.
- Оптимизация JavaScript.
- Обзор аудитории
Основным критерием, который должен определять, какие методы и в каком объеме стоит применять, естественно, будет аудитория ресурса. Для каждого сайта можно выделить несколько характерных групп страниц, которые посещаются тем или иным типом аудитории. В первую группу войдут веб-страницы, на которые заходят всякий раз новые пользователи. Во вторую группу войдут страницы, аудитория которых также часто меняется, однако, часть ее может просматривать страницы неограниченное число раз. Большинство сайтов, которые «живут» на поисковом трафике, являются замечательным примером ресурсов, полностью подходящих под эту группу. Для таких сайтов, в первую очередь, стоит рассмотреть методы уменьшения числа запросов (CSS Sprites), также возможную минимизацию всех текстовых файлов (HTML, CSS, JS).Наконец, к третьей группе можно отнести все остальные страницы, а именно те, аудитория которых в большей степени постоянна. В этой группе наиболее действенным будет, конечно же, кеширование и оптимизация скорости работы JavaScript и Flash-анимации.
Оптимизация времени загрузки сайта: сжатие и архивирование
Основными инструментами для уменьшения объема данных являются разнообразные минимизаторы и обфускаторы (для JavaScript-файлов), архивирование и также ряд утилит для уменьшения размера изображений. Давайте рассмотрим их по порядку.
Как показало проведенное тестирование средств сжатия CSS, лучше всего с этой задачей справляется проект CSS Tidy (примерно на одном уровне с ним идет YUI Compressor), который вместе с дополнительным архивированием файлов позволяет получить выигрыш до 85%.
Для JavaScript-файлов ситуация несколько интереснее. Если применять архивирование, то лучше всего использовать YUI Compressor, так как он, в среднем, сжимает в этом случае лучше. Если архивирование для JS-файлов применять нельзя, то лидером в сжатии является Dean Edwards Packer, однако, он вносит дополнительные издержки на свою «распаковку». Как показали исследования, для пользователей, которые будут, в основном, загружать JavaScript из кеша, лучше использовать сжатие без обфускации.
использование архивирования через mod_gzip для Apache способно существенно уменьшить размер загружаемых файлов. Однако, в случае очень быстрого канала у пользователей (например, локальный ресурс) и ограниченных ресурсов сервера (высокая удельная нагрузка на создание страницы) будет разумнее сжатие не использовать.
Также стоит для архивированных файлов добавить соответствующие заголовки (Cache-Control:private), чтобы избежать ряда проблем с кеширующими прокси-серверами. Для архивирования CSS- и JS-файлов также нужно исключить Safari и Konqueror из тех браузеров, которым можно отправлять gzip-файлы: эти браузеры до последнего времени не умели их корректно распознавать.
Уменьшение размера изображений
Для большинства графических элементов рекомендуется использовать формат PNG, так как он более экономичен, чем GIF. Однако, для небольших изображений GIF-формат может оказаться лучше. На данный момент PNG-изображения поддерживаются, практически, всеми браузерами, поэтому вы ничего не потеряете, если будете использовать его.
Сейчас существует проблема с поддержкой альфа-канала в Internet Explorer (которую уже исправили в 7 версии), однако, в версиях ниже 7 (5.5 и 6) она решается через ImageAlphaLoader (с помощью CSS expressions, CSS хаков или JavaScript), что позволяет использовать полупрозрачность, практически, в полном объеме.
В случае проблем с совпадением цветом (опять-таки в Internet Explorer) рекомендуется удалить из изображения gamma-чанков. В этом также может помочь ряд утилит, уменьшающих размер PNG-изображений: например, pngcrush. Для уменьшения размера JPG-изображений можно применить утилиту jpegtran, которая не затрагивает цветовые данные изображения, а удаляет комментарии и другие мета-данные.
Для анимированных изображений стоит использовать либо GIF-изображения с несколькими кадрами, либо DHTML-анимацию (JavaScript + PNG/JPEG).
Семантическая верстка
Когда разговор заходит про уменьшение размера кода, очень часто забывают про переход на семантическую разметку вместо табличной. Однако, она способна уменьшить не только время разработки backend-логики за счет более прозрачной структуры блоков, но и «облегчить» frontend-часть, сократив размер HTML примерно на 30%.
Сразу хочу заметить, что строгое следование семантике может отрицательно сказаться на размере кода, поэтому вам придется решить, что для вас важнее: поддержка последних тенденций (например, из мира микроформатов) или скорость загрузки страницы, например, интернет-магазина. Возможно, в ряде случаев будет разумно применить более простую спецификацию, сократив тем самым общее количество тегов и размер картинок (для CSS Sprites).
Уменьшение числа запросов
Для уменьшения числа запросов при загрузке страницы применяют, в основном, техники слияния, адаптированные под разные типы данных. Например, для объединения CSS-файлов в один стоит использовать конструкцию
01
@media тип {селекторы для этого типа}
например,
01
@media print {.nonprintable{display:none}}.
Для уменьшения числа JS-файлов у нас гораздо больше простора для фантазии. Можно просто создать один большой файл со всеми используемыми вызовами и библиотеками. Можно создать один внешний файл, который будет загружать библиотеки по мере необходимости. А можно с помощью комбинированного обработчика событий window.onload начать загрузку всех необходимых файлов сразу по получению HTML-кода.
используя технику «ненавязчивый» JavaScript можно добиться существенного визуального ускорения при загрузке сложного интерфейса или веб-страниц с нетривиальной логикой.
CSS Sprites
Наиболее популярной техникой для объединения изображений является CSS Sprites (или CSS Image maps), когда для отображения нескольких (десятков или даже сотен) изображений используется один ресурсный файл. Она дает ощутимый выигрыш в скорости загрузки при использовании анимационных эффектов (например, смене изображения при наведении мыши), а также при большом количестве иконок на странице.
Читать про CSS Sprites (откроется в новой странице)
Экстремальная оптимизация
Под экстремальной оптимизацией я понимаю максимальное уменьшение размера файлов и их количества, может быть, даже в ущерб браузерной совместимости.
В качестве характерного примера использования таких техник можно примести главные страницы Яндекса и Yahoo!, на которых CSS- ш JS-файлы кроме стандартной минимизации еще и включены в итоговый HTML-код, а сам HTML отдается в виде gzip-архивов.
Логическим продолжением в данном случае будет использование схемы data:URL и base64-кодирования для подключения фоновых и обычных изображений. Результирующий размер gzip-файла увеличится на 5–10% (от размера изображения), однако, при этом удастся сэкономить один запрос к серверу. С помощью несложных вычислений можно подсчитать, при каком размере файла это рационально применять.
Однако, Internet Explorer не поддерживает эту технику (до версии 7 включительно). Для него можно использовать специальные хаки (в том числе, * html), условные комментарии или mhtml-схему, которая обеспечивает, практически, ту же функциональность, что и data:URL.
Кеширование
Основной техникой для ускорения загрузки страницы для постоянных посетителей является кеширование, которое может свести число запросов к серверу для отображения страницы к минимуму (в идеале, к нулю).
Читать про Кеширование (откроется в новой странице)
Параллельные загрузки
Для уменьшения удельного времени ответа от сервера при загрузке большого числа файлов можно разделить загрузку на несколько потоков (серверов). Сами сервера для такой цели (быстрой отдачи статических ресурсов) лучше настраивать под «легким» окружением (например, nginx). В качестве балансирующего параметра можно рассматривать как распределение по географическому принципу (например, кластеры в США, Европе, Азии), так и по нагрузке (пул свободных серверов определяется каждый раз при загрузке страницы). Также возможно использование балансировки на клиенте для достижения того же эффекта.
В качестве основных проблем стоит отметить необходимости создания хеш-функции от имени файла, чтобы один и тот же файл загружался только с одного сервера, иначе браузер будет запрашивать его с серверов-зеркал, пока не забьет кеш всеми его копиями. Также стоит ограничиться 4 хостами (для большого числа файлов), для небольшого (15–25) стоит использовать не более 3. 2 хоста разумно использовать, только если число файлов превосходит 10 из-за дополнительных расходов на распознавание имени в DNS-таблице.
Оптимизация JavaScript
Чуть ранее я уже упоминал про возможность загружать необходимые для отображения страницы JavaScript-файлы, фактически, после ее загрузки. Однако, есть еще и пара нюансов. Например, ваш сайт должен полностью функционировать и без JavaScript (должны осуществляться переходы по ссылкам, первоначальный вид страницы должен формироваться на сервере). Это позволит повысить индексируемость сайта и обезопасит тех пользователей, у которых ваши скрипты не работают по тем или иным причинам.
используйте возможности CSS по максимуму. Вы не сможете отобразить страницу в браузере лучше, чем сам браузер, поэтому оставьте всю тяжелую работу по рендерингу для него (это относится к анимационным эффектам при наведении на кнопки, изменению разметки при изменении размеров окна и т.д.). CSS-движок, в среднем, работает быстрее, чем JavaScript. Также посоветую избегать использования CSS expressions либо оптимизировать их, чтобы они исполнялись только один раз на странице.
Обновляйте DOM-дерево большими кусками. DOM-Обращения ресурсоемки, это почти как база данных для серверных приложений. Чем меньше будет у вас работы с DOM, тем быстрее будет ваш JavaScript. Отдельное слово по поводу обработчиков событий: сводите их количество к минимуму. В идеале, стоит повесить один-единственный onclick на «body» и обрабатывать уже источник клика. Если вам требуются менее глобальные эффекты — просто ограничьтесь одним обработчиков на блоке, в котором заключена требуемая область. Большое количество обработчиков событий (которые еще и забывают убирать из изменении HTML-кода на странице) приводит к утечкам памяти в IE.
ш несколько общих советов: кешируйте глобальные переменные в локальные (однако, тут могут быть нюансы, особенно с цепочками вызовов функций), избегайте использовать eval и setTimeout / setInterval (которые выполняют eval на передаваемую в качестве аргумента строку). Вместо этого можно использовать анонимные функции.
01
(function(){ ... }())
При осуществлении тяжелых вычислений (например, подгрузка данных или сортировка больших массивов) стоит обновлять интерфейс пользователя, чтобы он знал, что выполняются какие-то действия, и мог немного подождать. Однако, тут главное не переусердствовать с уведомлениями: ведь каждое обновление страницы занимает некоторое время, и накладные издержки на него могут оказаться много больше «полезного» времени.
Статья сильно урезана
Полную статью можно прочитать на сайте www.webo.in: Оптимизация времени загрузки сайта
Тематические статьи