В то время как масштабируемость серверной части интернет проекта - сложное дело, требующее тщательного планирования, большинству сайтов можно обойтись существенно более простыми способами для повышения визуального быстродействия с точки зрения пользователей. О небольшой части из них я и хотел Вам сегодня рассказать.
Мотивация
Если воспользоваться инструментами для анализа времени загрузки страницы (например Firebug или Chrome Developer Tools), то не сложно обратить внимание на тот факт, что во многих случаях существенную часть ожидания загрузки страницы проходит в процессе загрузки внешних файлов, требуемых для рендеринга страницы:
- Изображения
- Файлы стилей
- Файлы JS-скриптов
На этот интервал времени абсолютно никак не влияет используемый язык программирования и баз данных, основных способов повлиять на него в меньшую сторону несколько:
- Вынести на отдельный (под)домен (позволяет браузеру качать больше файлов одновременно)
- Отредактировать HTML для избежания блокировок (так называемого "водопада")
- Настроить HTTP-сервер на предмет правильных заголовков Expires и Etags
- Воспользоваться для отдачи статики nginx или аналогом
- Сменить интернет-канал у сервера или сам сервер
- Воспользоваться услугами CDN (Content Delivery Network)
- Уменьшить размер передаваемых файлов
Сейчас я хочу остановиться на последнем пункте в отношении изображений, про скрипты, стили и остальные методы стоит поговорить отдельно в другой раз.
Выбор правильного формата изображений
Первым шагом по снижению объемов изображений должен быть выбор адекватного назначению изображения формата:
- JPEG - для всех фотографий
- GIF - исключительно для анимации (например для крутящейся загрузки)
- PNG - для всего, что не является фотографией или анимацией: иконки, графики, элементы интерфейса
GIF
На многих сайтах до сих пор по старинке используется этот формат изображений, не смотря на то, что PNG при таком же качестве имеет меньший размер файлов.
Рецепт лежит на поверхности: конвертируйте все GIF в PNG. Проще всего это сделать с помощью ImageMagick:
# Конкретный файл
$ convert foo.gif foo.png
# Все файлы в директории
$ mogrify -format png *.gif
# Или OptiPNG:
$ optipng *.gif
Дальше все просто: работаем с этими изображениями как и с остальными PNG, о чем пойдет речь ниже.
PNG
К сожалению, многие редакторы изображений сохраняют PNG-файлы совершенно не заботясь об их размере.
Но за многие годы была разработана масса различных утилит, исправляющих данную ситуацию. Основных принципа, на которых они основываются, четыре:
- Удаление лишнего: так как PNG - расширяемый формат, далеко не все данные и заголовки требуются для отображения изображения в браузере. Их можно смело выкинуть.
- Изменение типа PNG: использование только оттенков серого или произвольной палитры приемлемо для многих случаев, что по сравнению с полной гаммой существенно снижает размер изображения
- Использование подходящего "фильтра": они являются шагом перед сжатием изображения, правильный фильтр позволяет компрессии работать эффективнее
- Оптимизация самой компрессии: использование более эффективного алгоритма
Примеры использования наиболее эффективных инструментов:
# optipng
$ optipng -o7 foo.png
# pngcrush
$ pngcrush -rem alla -brute -reduce foo.png foo.png.temp
$ mv foo.png.temp foo.png
# pngout
$ pngout foo.png
# advpng
$ advpng -z4 foo.png
JPEG
В отличии от PNG и GIF каждое сохранение JPEG файла приходят к потерям данных и, как следствие, снижению качества фотографии, без потерь могут выполняться только изменение комментариев, метаданных и повороты на 90/180/270 градусов. Основным инструментом для минимизации JPEG без потери качества является jpegtran, используется достаточно просто:
# обычный режим
$ jpegtran -copy none source.jpg > destination.jpg
# режим progressive
$ jpegtran -copy none -progressive source.jpg > destination.jpg
Прогрессивный режим заслуживает отдельного внимания:
- Основная особенность - в нормальных браузерах (не IE) такой JPEG быстро отображается в низком качестве, а по мере загрузки файла полностью качество изображения улучшается (обычный JPEG грузится сверху вниз)
- По объему файла этот тип JPEG начинает выигрывать у обычного начиная от размера файла в 10Кб
- Изображение менее 10Кб все равно слишком маленькое, чтобы от самого процесса прогрессивной загрузки был какой-либо толк
- Если хочется подробнее разобраться - читаем здесь
Заключение
Использование простых инструментов, описанных выше, позволяет сократить общий размер используемых на веб-странице изображений порой до 30%, а то и больше. Эффект, который дает этот процесс, конечно же зависит от "запущенности" ситуации, но в большинстве случаев тоже измеряется десятками процентов от общего времени загрузки страницы. Чтобы воспользоваться ими требуется всего несколько минут, что существенно меньше, чем попытки оптимизировать код или запросы к базе данных, не говоря уже о полной переработке архитектуры системы.
Если кто-то знает более эффективные приемы по уменьшению размеров изображений - прошу в комментарии. Про скрипты и стили поговорим отдельно :)
Основным источником информации послужила статья Stoyan Stefanov, которую я сильно подсократил до тех инструментов, которыми пользуюсь сам на практике, и моментов, которые считаю интересными. Желающим покопаться в этой тематике поглубже рекомендую изучить весь его блог - можно найти много интересного. Про подписку на Insight IT тоже не забываем)