Довольно нередко можно наблюдать ситуация, когда производительность сайта в клиентском браузере недооценивается. Особенно часто это происходит в тех случаях, когда сайт собран «из коробки» и не специализирован под выполнения тех или иных конкретных задач. Ситуация может быть дополнительно осложнена низкоскоростным каналом связи у целевой аудитории пользователей.
В общем, все вышеописанное было справедливо для сайта PERSPEKTIVA IMPEREAL. Перед началом оптимизации главная страница «весила» около 500 Кб, загружала большое количество внешних скриптов (порядка 150 Кб), и ее невозможно было нормально загрузить по модему. Ниже рассказывается, какие методы были применены для улучшения скорости загрузки. Может быть, общий ход проведения оптимизации поможет и вам точнее проанализировать ситуацию и применить требуемые действия.
Для анализа скорости загрузки я стандартно использую сам Web Optimizator и Firebug NET Panel. Почему два инструмента? С помощью Firebug можно достаточно точно отследить все запросы на странице из реального браузера. Однако Firebug временами не выдает всех запросов к файлам стилей и скриптов. Также тяжело бывает с кэшированием. Для полного аналитического разбора я использую только анализатор скорости загрузки. После проведения проверки хорошо видно, какие файлы кэшируются (выставлено время кэша), у каких есть ETag
или Last-Modified
, а также, что более существенно, сразу виден потенциальный выигрыш при минимизации файлов.
С помощью визуальной оптимизации удобно посмотреть, как изменится диаграмма загрузки сайта, если применить все оптимизационные меры. И поскольку расчет производится аналитически, это обеспечивает достаточно большую точность (не нужно перезамерять по два-три раза, чтобы избежать случайных сетевых задержек).
Разобрав основные проблемные места сайта с помощью указанных инструментов, намечаем путь действий — и вперед. Дополнительно можно оценить время ответа с сервера для динамических файлов, и понять, нужно ли что-то вытворять с серверной частью.
Базовые действия по оптимизации чрезвычайно просты: нам нужно объединить все текстовые файлы и применить для них gzip
-сжатие. А также включить кэширование на достаточно длительный срок (это позволит значительно ускорить, по крайней мере, открытие последующих страниц на этом сайте). Все это делается несколькими строками в конфигурационном файле Apache (httpd.conf
или .htaccess
):
AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE image/x-icon AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/x-javascript BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch Konqueror no-gzip BrowserMatch \bMSIE !no-gzip !gzip-only-text/html Header append Vary User-Agent <FilesMatch .*\.(css|js|php|phtml|shtml|html|xml)$> Header append Cache-Control private </FilesMatch> ExpiresActive On ExpiresDefault "access plus 1 month" <FilesMatch .*\.(shtml|html|phtml|php)$> ExpiresActive Off </FilesMatch>
Данный фрагмент кода включает сжатие для тех типов файлов, для которых это разумно сделать. Затем отключает сжатие для старых и неподдерживаемых браузеров. Заголовки Vary User-Agent
и Cache-Control private
нужны для корректной обработки сжатия на этапе локальных прокси-серверов (чтобы они пропускали название браузера и не кэшировали сжатую версию и не отдавали ее тем пользовательским агентам, которые это не поддерживают). Затем на все файлы накидывается кэширование на один месяц, а затем для динамических файлов (HTML) оно отключается. Если на сервере не установлены какие-либо модули, то возникнет 500-ошибка. Чтобы ее избежать, можно обернуть все конструкции в условия существования соответствующих модулей, а потом удалить неработающие правила.
Объединение и минимизация файлов может быть достаточно проблематичным занятием, но для этой цели я использую пакетную оптимизацию, загружаю один архив со всеми файлами, которые требовалось оптимизировать — и на выходе получаю уже готовые к применению версии.
Следующим шагом по соотношению эффективность / сложность будет работа с изображениями. Начать лучше всего с создания CSS Sprites. Я руководствуюсь всеми принципами, изложенными в соответствующей статье. Естественно, что при создании CSS Sprites вам нужно будет видоизменять стили для страницы, но обычно это достаточно несложно при должной сноровке. В любом случае я рекомендую всегда делать резервные копии изменяемых файлов — это позволит быстро понять, где допущена ошибка, и не менее быстро ее исправить.
Попутно все gif-изображения переводятся в pbg-формат. Затем архив с изображениями прогоняется через всю ту же пакетную оптимизацию. Отдельным пунктом для сайта www.vaclavak.ru стоит упомянуть работу с анимированными gif. В исходной точке все банеры занимали порядка 180 Кб. При оптимизации повезло (удалось удалить ненужные кадры и немного уменьшить палитру), в итоге размер рекламного блока сократился вдвое.
В результате проведенных действий размер страницы уменьшился до 350 Кб, чтобы было совсем неплохо, учитывая «тяжелый» дизайн сайта.
Однако этого оказалось недостаточно.
Для более точного анализа реальной картины можно воспользоваться счетчиком времени загрузки, который замеряет полное время загрузки у всех посетителей сайта для произвольной страницы. Установка его чрезвычайно проста: нужно получить код, установить его максимально близко к началу страницы в шаблоне (идеально — сразу после title
), и пару дней собирать статистику (зависит от числа хитов, если на сайт заходит несколько десятков тысяч ежедневно, то хватит и дня или пары часов).
После установки счетчика обнаружилась следующая картина: среднее время загрузки (уже оптимизированного) сайта составило 16 секунд, за 4 секунды страницы загружались у 58% пользователей. На диаграмме приведено распределение времени загрузки (в секундах) по числу пользователей.
Было решено существенно переработать логику загрузки страницы: вынести рекламные блоки в пост-загрузку, а загрузку самого JavaScript «отложить». Все этого было сделано в лучших традициях, которые описаны в статьях разгоняем счетчики и «ненавязчивая» реклама. Google Analytics был вынесен на событие OnDOMReady
(для точности измерения посещений), остальные — на window.onload
.
В результате, на странице сразу загружалось только основное содержание. Сразу после него — Google Analytics и дополнительные библиотеки для галереи изображений (но только на тех страницах, где это было нужно: в частности, это не требовалось для главной страницы). Затем шла загрузка рекламных банеров, информера с курсом валют и погоды. В самом конце на страницу (в самый низ) вставлялся блок с остальными счетчиками. Загрузка почти всего (99% кода) JavaScript была переделана на «ненавязчивый» манер.
Единственная сложность возникла с блоком валют, который вызывался через внешний JavaScript-файл, который в свою очередь содержал document.write
. Его пришлось вставлять через динамический iframe
, который получал данные, а потом отправлял родительской странице. Поскольку информер этот достаточно тормозной, то получился значительный выигрыш во времени загрузки страницы после его вынесения в пост-загрузку.
После очередных замеров с помощью счетчика времени загрузки получилась следующая картина: среднее время загрузки — 7,3 секунды (ускорение более 100% от уже оптимизированного варианта), за 4 секунды сайт загрузился у 82% посетителей.
В результате наличия большого количества удобных инструментов удалось очень оперативно проработать клиентскую составляющую обычного, в общем, сайта. Только для широкополосного подключения скорость загрузки увеличилась в 7 раз (для коммутируемого доступа это число еще более значительно в связи с существенным уменьшением числа запросов, необходимым для первичного отображения страницы).
Сам процесс оптимизации относительно оценки самого Web Optimizator можно представить следующим образом (в этом уже может помочь история проверок сайта):
Возможно, не все из описанных шагов необходимы для среднестастического сайта, рассчитанного на рядовых пользователей Интернета, но сам процесс оптимизации (с простого к сложному, от более эффективного — к менее эффективному) должен, по-видимому, протекать именно таким образом.