Опубликован: 16.02.2009 | Доступ: свободный | Студентов: 1429 / 138 | Оценка: 4.26 / 4.17 | Длительность: 16:10:00
ISBN: 978-5-9963-0024-2
Лекция 4:

Уменьшение числа запросов

PHP Speedy

К сожалению, почти все описанные выше методы применимы только на стадии разработки или существенной оптимизации и требуют участия опытных разработчиков для своей интеграции. Но возникает резонный вопрос: может быть, уже существуют какие-либо автоматизированные решения для автоматического объединения CSS- или JavaScript-файлов? И что делать, если хочется ускорить сайт на существующей платформе одной из популярных CMS, где в коде уже "сам черт ногу сломит"?

В таких случаях можно использовать проект с открытым кодом PHP Speedy (http://aciddrop.com/php-speedy/) — РНР-скрипт, который обеспечивает расширенное кэширование и сжатие компонентов страницы, не требуя никаких модификаций вручную. Достаточно только установить скрипт на сервере и сделать несложные настройки, заключающиеся в указании директории с самим сайтом и папок для кэширования файлов. Скрипт умеет автоматически склеивать все CSS- и JavaScript-файлы, кэшировать их, применяет оптимизацию (с помощью пакета Minify, http://code.google.com/p/minify/, о котором уже шла речь выше), а также gzip -сжатие. На выходе мы получаем автоматическую оптимизацию сайта совершенно бесплатно. Хотя, конечно, не следует рассматривать это как конец — для начала такое решение вполне приемлемо, однако, для достижения максимальной производительности сайта придется со временем все больше и больше настраивать некоторые моменты вручную и применять советы из этой книги.

Для владельцев блогов на популярном движке Wordpress есть специальное расширение на основе этого решения, добавляющее оптимизацию буквально одним кликом в панели управления. Решение очень даже полезное: блоги часто расположены на слабых хостинговых площадках, а популярность проекта может возрасти буквально после пары публикаций. Площадка может быть к этому просто не готова, да и сам Wordpress не является вершиной оптимизации с точки зрения нагрузки.

Техника CSS Sprites

Рассмотрев все аспекты объединения текстовых файлов, перейдем к графической и мультимедийной информации. Сейчас уже много где написано и упомянуто про технику CSS Sprites (или CSS Image Maps). Ниже приведены несколько примеров и полезных ссылок. И пара советов, где и как этот метод может быть применим наиболее оптимальным образом. Сама техника заключается в том, что мы создаем комбинированное изображение, из которого затем "вырезаем" с помощью CSS-свойства background-position нужный нам в данном случае кусок. На текущем уровне поддержки браузерами (порядка 99,9%) она является просто обязательной для любого уважающего себя веб-ресурса, так как позволяет сократить число запросов к серверу — а кроме этого отделить поведение от представления, и возложить труд по анимации на CSS-движок браузера, а не на JavaScript-движок (т. е. это будет работать даже с выключенными скриптами), и много-много прочих "вкусностей". Но обо всем по порядку.

Простой rollover-эффект

Обычно таким термином называют смену графической картинки при наведении на нее мыши — своеобразный призыв к действию (как его любят называть маркетологи). У веб-мастеров сложилась дурная практика делать такие эффекты через onmouseover / onmouseout на картинках.

Это прямое нарушения принципа разделение представления от поведения и несемантическая (в лучшем случае, в худшем — еще и невалидная) верстка. И вообще, это очень плохо. В данном случае это делается средствами CSS и является семантически правильным (в большинстве HTML-документов — это ссылка, но с элементами форм приходится немного повозиться, однако тоже ничего сверхъестественного). Пример: при наведении просто показывается другая картинка.

 Пример фонового изображения для простого rollover-эффекта. Источник:www.websiteoptimization.com

Рис. 4.1. Пример фонового изображения для простого rollover-эффекта. Источник:www.websiteoptimization.com

Соответствующая часть в CSS-коде будет выглядеть примерно так:

a.sprited {
 background: yellow url(http://site.ru/img/button.png) 0 0 no-repeat;
 width: 100px;
 height: 20px;
}
a.sprited:hover {
 background-position: -100px 0;
 background-color: red;
}

При наведении на ссылку фоновое изображение под ней "уедет", и покажется правая его часть (ибо она изначально скрыта жесткими размерами самой кнопки). Дополнительно мы обеспечили обратную совместимость для тех пользователей, у которых отключены картинки. Для них мы меняем цвет фона при наведении (если картинки в браузере включены, то изображение покажется поверх цвета).

Сложный rollover-эффект

Под таким термином стоит понимать те случаи, когда в одном файле содержится несколько "динамических кнопок". Например, это может быть такое изображение:

 Пример фонового изображения для сложного rollover-эффекта. Источник:www.spegele.com

Рис. 4.2. Пример фонового изображения для сложного rollover-эффекта. Источник:www.spegele.com

Проблемные места в IE

В некоторых версиях IE изменение расположения фона при наведении мыши отрабатывает не совсем корректно, и браузер запрашивает исходную фоновую картинку с сервера еще раз, что вызывает "мигание" картинки. Одним из вариантов борьбы с такой проблемой может стать изменение не позиции фонового элемента, а его прозрачности. Например, мы можем сразу задать параметры фона для элемента и его прямого потомка, а при наведении мыши менять фон дочернего элемента на прозрачный, тогда фон родителя будет просто просвечивать:

<a href="/"><span>Начало</span></a>

a {
 background: yellow url(http://site.ru/img/button.png) 0 0 no-repeat;
 display: block;
 height: 20px;
 width: 100px;
}
a span {
 background: red url(http://site.ru/img/button.png) -100px 0 no-repeat;
 display: block;
 height: 20px;
 width: 100px;
}
a:hover span {
 background: transparent;
}

К сожалению, этот метод предполагает появление у элемента несемантического потомка для обеспечения графических эффектов. Более стандартным вариантом будет вызов специфичного для IE метода backgroundImageCache (через try или любое другое условие, гарантирующее обратную совместимость с остальными браузерами):

try {
	document.execCommand("BackgroundImageCache", false, true);
} catch (e) {}

В данном случае мы форсируем кэширование фоновых изображений, что предотвращает описанную выше ошибку.

CSS Image map

Этот пункт стоит намеренно выделить, ибо он подразумевает более свободное использование ресурсного файла для "подсветки" какого-либо изображения при наведении. Если в предыдущих случаях области были одинакового размера, то тут уже размер областей может быть, вообще говоря, произвольным. Одним из преимуществ такого подхода является совмещение разных областей, чтобы они занимали минимум места. Эта техника как раз и заменила классический Image Map.

 Пример изображения для CSS Image Map. Источник:www.acronis.com

Рис. 4.3. Пример изображения для CSS Image Map. Источник:www.acronis.com

Статичные картинки

Кроме динамических эффектов CSS Sprites широко используется и для объединения статических изображений. Давайте рассмотрим различные плюсы и минусы этого подхода. Основной опасностью склеивания большого количества иконок в одном месте являются артефакты при увеличении шрифта: посторонняя часть фонового изображения проявляется совершенно не в том месте, где его ожидали, и у пользователя возникает ощущение, что страница "разваливается". Блок становится выше или длиннее, запаса полей данного изображения уже не хватает, в результате у одного элемента отображается сразу несколько иконок. Непорядок. Как с ним бороться, будет рассказано немного ниже в общих советах по созданию ресурсных картинок для CSS Sprites.

В общем случае нужно жестко ограничивать размеры контейнера, у которого заданы определенные фоновые картинки, чтобы даже при увеличенном тексте картинка не "ломалась" (однако текст может стать нечитаемым из-за обрезания по границе блока). Как бороться с последней напастью, также будет рассказано в конце раздела. В некоторых случаях возможно также объединение всех фоновых изображений на странице в одно-единственное. Такой подход значительно сокращает число запросов к серверу, однако влечет за собой и технологические сложности. Как пример можно привести следующее изображение:

 Пример фонового изображения "все-в-одном"

Рис. 4.4. Пример фонового изображения "все-в-одном"

Онлайн-генераторы

https://www.toptal.com/developers/css/sprite-generator. Обладает довольно минималистичным дизайном, есть возможность загружать несколько исходных файлов.

http://www.printf.ru/spritr/. В этом инструменте есть возможность загружать несколько файлов, очень милый дизайн, но в целом настроек мало.

http:// spritegen.website-performance.org Тут очень много настроек, также можно гибко создавать и сам CSS-фрагмент, но все картинки нужно загружать одним архивом.

Полезные советы

Итак, самое вкусное. Для начала стоит разбить все фоновые картинки на 5 групп (однако пятая группа может быть объединена с любой из первых четырех).

  1. Анимированные картинки.
  2. Те, которые предполагается повторять по всем направлениям ( repeat ).
  3. Те, которые предполагается повторять по горизонтали ( repeat-x ).
  4. Те, которые предполагается повторять по вертикали ( repeat-y ).
  5. И те, которые предполагается показывать только один раз ( no-repeat ).

Откуда взялось разделение на такие группы? Из очень простых соображений: если картинка будет повторяться по какому-то направлению, то по этому направлению она должна быть одна-единственная в своем "окне", иначе повторяться будет не только она одна. Также стоит ориентироваться на общий размер файла в 10–20 Кб: если файл получается больше, то лучше подключать больше одного (соображения по разбиению файлов по размеру более подробно приведены в пятой главе).

Далее, все картинки из второй группы (повторяющиеся по всем направлениям) оставляем как есть (вообще говоря, можно подумать над их преобразованием в стилевые правила для самых простых случаев, но это уже тема для отдельной дискуссии). Все картинки из третьей группы можно склеить по вертикали (тогда в своем горизонтальном окне они будут единственными), все картинки из четвертой группы — по горизонтали. Что же делать с пятой группой?

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

 Пример фонового изображения с расположением картинок "лесенкой"

Рис. 4.5. Пример фонового изображения с расположением картинок "лесенкой"

Описанная выше проблема с изменением размера надписей в фиксированных кнопках (фон у них фиксированный, поэтому мы не можем их раздвигать при увеличении шрифта, и он обрезается) может быть преодолена путем разбиения фона на 4 части (угловые) и задания соответствующего цвета фона для всех элементов. Однако это повлечет наличие как минимум 4-х вложенных элементов для отображения каждого угла. Не во всех случаях это допустимо семантически. Да, можно создавать дополнительную разметку при помощи JavaScript, но насколько оно того будет стоить? Это лучше решать в каждом конкретном случае.

Давайте теперь перейдем к методам, позволяющим вставлять графическую информацию непосредственно в текстовые файлы без необходимости запроса внешних ресурсов.