Оптимизация работы сайта. Часть 2. Сжатие мелких изображений

Сжатие сайта путем включения мелких изображений в CSSПо мотивам предыдущего поста о необходимости сжатия составляющих частей сайта – в продолжении рассмотрим также и возможность сжать мелкие изображения.  Сразу оговорюсь, что речь идет о мелких статических изображениях, не меняющихся, как правило иконок, которые встречаются почти что на каждой странице сайта.

Вы замечали иногда, что сайт загружается, сайт загрузился. Такой красивый … Но стоит навести на кнопочку – и она подсвечивается через некоторое время, а то и дергается как-то непонятно в первый раз. Или такое: Загружается сайт, а там много мелких изображений … и все постепенно заполняются. А в случае плохой связи – некоторые и не заполняются, вы обновляете страницу – грузятся одни и не грузятся теперь предыдущие … В общем – Ад. Какие есть варианты?

 

1 Способ. Есть такая технология – спрайты. Мы прочем все мелкие изображения в один графический файл. Один файл качается быстрее чем 10 мелких, да и грузится одинаково, а картинка выбирается сдвигом фона из этого файла. Технология вполне успешная. Она хорошо себя зарекомендовала на стандартных элементах одного размера – кнопках к примеру. И сложно –нужно каждый раз каким- то образом генерить этот спрайт из картинок. Если у какое-то изображение – нужно сделать чуть шире – нужно сдвигать все остальные изображения и прописывать это в скриптах и стилях … бяка в общем. Мы такой вариант рассматривать не будем.

2 Способ. Вы, наверное, знаете - мелкие графические файлы можно включать в CSS файл. Вы также, наверное, знаете, что это фичу поддерживают все браузеры, за исключением IE7 и ниже? По секрету сообщаю, что доля таких браузеров – на сегодняшний день – порядка 1,5% во всем мире. И эта доля стремительно падает. Да и для них можно будет выставить дополнительный файл (костыль), дополняющий оригинальный ссылками на изображения.

По этому – все мелкие и часто используемые графические файлы – будем включать в один CSS. Каким образом это ускорит работу сайта – очевидно. Вместо 10-100 точечных запросов на загрузку изображений – браузер будет тянуть один файл, да еще сжатый при помощи GZIP.

На обращение к каждому файлу тратится множество ресурсов, как у клиента, так и у сервера. Клиенту надо проверить наличие и версию файла у себя в кеше, сделать запрос на сервер. Серверу надо проверить файл у себя, считать его, передать. И так по многу раз для каждого посетителя. Также учитывайте, что у каждого браузера стоит ограничение на одновременное обращение к одному домену – 2 файла.

Функция, которая по всему файлу произведет нужную замену – умещается в 2х строках


function addimages($buffer){
return preg_replace('/url\(([\:-\w\/\.]*)/ie','"url(data:image/".((substr("\\1",-4)==".png")?"png":"gif").";base64,".base64_encode(file_get_contents("\\1"))',$buffer);
}

Она несколько доработана, чем аналогичная на хабре. В частности – работает на вложения в любых каталогах, а также при ссылках через http. Ее еще можно доработать, чтобы программа вносила и не графические части (шрифты например)

Прежде чем пользоваться данным кодом – файл нужно подготовить. Нужно убрать апострофы в адресе (скрипт пока такого не умеет)) url апостоф апостроф. Он там не нужен, а скрипт обрабатывать такое не умеет.

Еще одно действие Вам нужно будет сделать один раз. Если одно изображение используется в нескольких стилях – их нужно собрать в один через запятую и


.style_a,.style_b{
Background-image: url(../images/add.png);
}

Также Вам придется для лучшего эффекта – все конструкции с использованием тега IMG заменить простым фоном. Для семантики – это очень удобно, но не всегда приемлемо. Используйте Display: inline-block. Если не ошибаюсь – он лучше всех заменяет имеющиеся стили.

А что про старые браузеры. Каждый 80й посетитель – не увидит мелких изображений. Для них мы можем предусмотреть в дополнение к данному файлу стилей – хвост от оригинального. Пусть клиент скушает 2 стиля вместо одного. С точки зрения разделения браузеров – отличить IE7 и ниже от других – не сложно

Условимся, что стили для IE – будут иметь хвост на конце STYLE_IE.CSSGZ

И чтобы нам не содержать у себя 2 копии файлов и вести их одновременно – давайте сделаем условный разделитель, прочитав который скрипт бы самостоятельно вычленил часть с изображениями от остальной части. Пусть это будет строка /****IMAGES****/

И если стиль содержит не только фон – нужно его описывать в секции сверху и в секции снизу.

Теперь – если мы хотим для старых браузеров дополнить изначальный стиль – пишем в HTML строку

<link href="css/style.cssgz" rel="stylesheet" type="text/css" />
<!--[if lte IE 7]><link href="css/style_ie.cssgz" rel="stylesheet" type="text/css" /><![endif]-->

Всем браузерам данная строка будет понятна, а IE7 и ниже – еще и доступна.

Помните наш код? Вот как он будет выглядеть полностью доработанным

<?php
//require 'cssmin-v3.0.1.php';
if ($handle=opendir('.')){
                while(false !== ($file=readdir($handle))){
                               if ($file == '.' or $file == '..' or is_dir($file)) continue;
                               if (substr($file,-4) != '.css') continue;
                               $filename=substr($file,0,-4);
                               $css=file_get_contents($file);
                               $filepart=explode('/****IMAGES****/',$css);
                               if (isset($filepart[1]))file_put_contents($filename.'_ie.cssgz',gzencode(compress($filepart[1]),9));
                               $csscompress=compress($css);
                               //$csscompress=CssMin::minify($css);
                               $cssimages=addimages($csscompress);
                               file_put_contents($filename.'.cssgz',gzencode($cssimages,9));
                }
                closedir($handle);
}
function compress($buffer){
                $buffer=preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!','',$buffer);
                return str_replace(array("\r\n","\r","\n","\t",'  ','   ','    '),'',$buffer);
}
function addimages($buffer){
return preg_replace('/url\(([\:-\w\/\.]*)/ie','"url(data:image/".((substr("\\1",-4)==".png")?"png":"gif").";base64,".base64_encode(file_get_contents("\\1"))',$buffer);
}

Берегите ресурсы хостинга. Берегите жесткие диски и скрежет головок при чтении кучи мелких файлов. Хостинг и пользователи вам скажут спасибо.

  • Автор: kosmom
  • Рейтинг: 0
  • Просмотров: 666
  • Комментариев: 1
  • Создан: 19.12.2012 11:07

Комментарии (1)

28.12.2012 14:29
Гость

спасибо. хорошая статья!