Опубликован: 16.06.2010 | Уровень: специалист | Доступ: платный
Лекция 5:

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

< Лекция 4 || Лекция 5: 12345 || Лекция 6 >

4.2.4. Практическое решение: сборка изображений


Дальше начинается самое интересное: как нам вышеописанные группы "склеивать"? Для этого используется следующий алгоритм:

  1. Изображения, для которых позиционирование задано в процентах и которые находятся внутри контейнеров с абсолютными размерами, корректируются, чтобы фоновая позиция была задана в аболютных единицах.
  2. repeat-x изображения (группа 3) объединяются все вместе по вертикали. Попутно правится ширина фоновых изображений (приводится к наименьшему общему кратному). В самое начало такого файла добавляются no-repeat изображения, подходящие по ширине (группа 1). Далее в самый низ файла записывается 1 изображение из группы 4. Больше 1 все равно никуда не войдет, поскольку нам нужно обеспечить свободное пространство ниже заявленной высоты фонового изображения. Это часто бывает нужно для плавного перетекания градиента в ровный цвет: градиент вставляется фоновой картинкой, которая заканчивается на фоновом цвете, а дальше продолжается уже этот цвет, заданный через background-color.
  3. Производятся абсолютно аналогичные действия с repeat-y.
  4. Далее изображения из группы 7 объединяются по вертикали (0 100% означает, что фон должен быть прижат к правому краю элемента, соответственно, весь спрайт будет "прижат" к правому своему краю).
  5. Аналогично с группой 8 — прижимаем все к низу. Естественно, что для всех групп мы учитываем первоначальное значение background-position.
  6. Рассчитываем позиционирование для изображений группы 1 (для этого подойдет и просто перебор отсортированных по площади или сумме квадратов измерений изображений: готовим матрицу, в которую пытаемся "вписать" очередное изображение; если не получается, то матрицу увеличиваем). При вписывании ради экономии процессорного времени можно проверять только 9 точек (8 по краям изображения и 1 в центре), чтобы убедиться, что на месте изображения еще ничего нет.
  7. Строим "лесенку" из изображений второй группы. Лесенку лучше строить с низа уже созданного спрайта из предыдущего пункта: тогда легко найти минимальный размер "дырки" между двумя группами изображений, чтобы сдвинуть "лесенку" вверх (и потом, возможно, влево). Конечно, поиск наиболее оптимального расположения — непростая задача. Но ее можно решить и в достаточно грубом приближении, которое описано выше.
  8. Итоговое изображение из пункта 4 прикрепляется к правому верхнему углу нашего сложного изображения (результат действия пунктов 6 и 7). Так как у каждого такого изображения задана допустимая высота и все они находятся вне "рабочей" зоны остальных no-repeat изображений, никаких рудиментов не возникнет.
  9. Аналогичным образом поступаем с изображением из пункта 5 — его располагаем в нижнем левом углу нашего спрайта.
  10. На выходе мы получаем 3 спрайта со всеми возможными случаями. В среднем размеры таких спрайтов будут лишь незначительно превосходить (если вообще будут) аналогичные "ручные" аналоги (в том числе за счет использования PNG). Естественно, можно в автоматическом режиме пропустить их через pngcrush или jpegtran. Стоит также предусмотреть, в каком виде будут создаваться полноцветные изображения: JPEG или PNG (последние больше по размеру, но гарантируют отсутствие потерь качества).

При расчете позиции картинки в конечном спрайте может помочь следующая схема:

Схема позиционирования фоновой картинки относительно элемента

Рис. 4.1. Схема позиционирования фоновой картинки относительно элемента

В силу громоздкости решения (в нем более 1500 строк кода) в полном объеме в данной книге оно не приводится, однако все описанные шаги уже применены в Web Optimizer (http://www.web-optimizer.ru/) (веб-приложении для автоматизации клиентской оптимизации). Одна из финальных версий алгоритма работает для инструмента Auto Sprites (http://sprites.in/), а с исходным текстом можно ознакомиться в SVN (http://code.googLe.eom/p/ web-optimizator/source/browse/trunk/Libs/ php/css.sprites.php).

Эту логику можно применить на любом этапе веб-разработки (как при начальном создании дизайна, так и при пострелизной оптимизации сайта). Библиотека для автоматического создания спрайтов распространяется по лицензии MIT (она позволяет использовать продукт где угодно и как угодно, но обязательно должна присутствовать ссылка на первоисточник, даже если используется не вся библиотека, а только ее существенная часть).

4.3. CSS Sprites и data:URI, или Microsoft и весь остальной мир

На стадии полной загрузки страницы браузер запрашивает картинки и FLash-анимацию, которые заполняют отведенные им места на странице. По мере появления элементов на странице пользователь ощущает, что страница загружается. Обычно окончание этой стадии совпадает для пользователя с окончанием всей загрузки.

Если говорить об ускорении этой стадии, то здесь одной из основных технологий будет именно технология CSS Sprites, которая уже отлично себя зарекомендовала в этом качестве. Однако у нее вместе с очевидными плюсами (значительное уменьшение запросов к серверу, кроссбраузер-ность) есть и несколько минусов. В частности:

  • несемантическая верстка в случае использования сложных спрай-тов. Это приводит к дополнительному времени создания документа (особенно существенно может быть для "старых" браузеров). (Более подробно о влиянии DOM-дерева на процесс загрузки страницы рассказывается в следующей лекции);
  • невозможность комбинирования нескольких осей повторения. Это не очень существенно, поскольку все использование CSS Sprites (как было описано в предыдущем разделе) можно свести к трем основным изображениям;
  • тяжесть изменения картинки в случае сложной геометрии;
  • отображение неверного фона при масштабировании.

4.3.1. data:URI

Есть ли выход из этого положения? Да, есть. Это технология data:URI, которая позволяет включать фоновые изображения прямо в CSS-файл в base64-виде. Плюсы данного подхода очевидны: не нужно "склеивать" несколько картинок в один файл, есть возможность объединять различные оси и анимированные с обычными изображениями, полностью отделить содержание (семантику документа) от его представления (оформления и дизайна), и т. д.

Но есть и ложка дегтя: IE вплоть до версии 7 не поддерживает data:URI. IE8 — уже да, но все остальные IE — нет. Что делать?

4.3.2. mhtml

Нам на помощь приходит технология mhtml (MIME HTML), которую поддерживает по умолчанию только IE (почти в полной мере) и Opera (начиная с версии 9.0). Она позволяет включать base64-данные в CSS-файл в виде комментариев. В этом случае сам файл выступает в двух ипостасях: как таблица стилей и как хранилище фоновых картинок.

Если мы объединим эту технологию с data:URI, то все будет хорошо. Правда?

4.3.3. Проблема 1: долгая предзагрузка

В случае включения фоновых картинок прямо в CSS-файл последний заметно увеличивается в размере (даже при использовании gzip-сжатия). Это значительно увеличивает время предзагрузки (если фоновых картинок больше 10—15 Кб), и пользователь дольше видит белый экран. Опять все плохо. Как быть?

Возможным выходом из сложившейся ситуации может стать подключение CSS-файла с фоновыми картинками по комбинированному событию window.onload, что вынесет загрузку элементов дизайна в ту область, где она изначально находилась: на стадию полной загрузки страницы или даже в пост-загрузку. В данном случае мы получаем полную аналогию метода CSS Sprites, только без заявленных выше неудобств.

4.3.4. Проблема 2: выключенный JavaScript

Описанный выше прием позволит облегчить загрузку только пользователей с включенным (или поддерживаемым) JavaScript (их порядка 9899%). Однако в ряде проектов это может быть недостаточно. Для оставшихся пользователей мы можем через <noscript> подключить нужный нам файл (и конкретно для них замедлить предзагрузку) или поместить вызов этого файла перед </body> (что в ряде случаев может быть аналогично подключению стилей в <head> ).

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

4.3.5. Проблема 3: Safari и window.onload

Из-за того, что Safari отличается алгоритмом обновления страницы (что позволяет значительно ускорить отображение самих страниц), для этого браузера не удается загрузить дополнительные стили после отображения первоначальной картинки (на стадии полной загрузки страницы). В этом случае Safari блокирует отрисовку картинки на экран и ожидает загрузку нового файла стилей.

На данный момент для Safari мы можем безболезненно загружать дополнительные файлы стилей только по полному событию window.onload.

4.3.6. Проблема 4: Microsoft, IE7 и Windows Vista

В результате проведенных исследований удалось установить, что в связи с проблемами безопасности в Vista mhtml-технология для отображения фоновых изображений не поддерживается. В этом случае единственным выходом будет подключение конкретно для этого браузера (через JavaScript) общего файла (с использованием CSS Sprites). Для пользователей IE7@Vista с отключенным JavaScript у нас нет другой альтернативы, чем загружать файл только с CSS Sprites.

Более подробно о создании автоматического решения, позволяющего решить все описанные проблемы, рассказывается в следующем разделе

4.4. Автоматизация кроссбраузерного решения для data:URI

Логотип duris.ru: Data:URI [CSS] Sprites. Источник: duris.ru

Рис. 4.2. Логотип duris.ru: Data:URI [CSS] Sprites. Источник: duris.ru

Многим профессиональным веб-разработчикам известны приемы оптимизации сайтов. Одним из способов оптимизации является применение CSS Sprites. Этим же разработчикам известно, какие существуют трудности с формированием, сборкой и пересборкой стандартных спрайтов. При использовании стандартных спрайтов полностью автоматизировать сборку для всех случаев проблематично, из-за специфики свойств background в CSS. Иногда камнем преткновения является свойство repeat фоновой картинки.

4.4.1. Data:URI CSS

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

Мучения со стандартным подходом применения CSS-спрайтов, а именно, трудности модернизации и, в некоторых случаях, сложности оптимальной компоновки заставили искать альтернативный вариант оптимизации загрузки изображений. Далее речь пойдет об использовании комбинированного метода: data:URI + mhtml. Более детально процесс создания изображений в этом формате описан в пятой главе книги "Разгони свой сайт".

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

Новый подход генерации CSS-спрайтов на основе data:URI решили назвать Data URI Sprites — DURIS.ru. Название немного необычное — но зато уникальное и хорошо запоминается.

4.4.2. Что это?

В первую очередь это полностью автоматический анализ и сборка CSS-спрайтов на основе data:URI.

Некоторые характеристики работы DURIS:

  • загрузка и анализ всех внутренних ( <style> ) и внешних ( <link> ) стилей;
  • выделение background-image в отдельный внешний стиль;
  • загрузка и кодирование в base64 всех изображений, которые найдены в стилях;
  • оптимизация правил с повторяющимися background-image в стилях;
  • удаление CSS-правил с отсутствующими на сервере изображениями (устраняет лишние ненужные запросы);
  • специальное подключение data:URI спрайтов для всех браузеров и отдельно для IE6, IE7 Vista (более детально в FAQ, duris.ru/faq/).

4.4.3. Зачем это надо?

Современный подход создания CSS-спрайтов:

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

4.4.4. IE и другие

В ходе разработки реализации data:URI спрайтов были проанализированы наиболее часто встречающие варианты CSS-правил. Также был учтен всеми любимый браузер IE. Кому еще не известно: IE не поддерживает до версии 8 технологию data:URI. Однако для него существует альтернативный вариант реализации спрайтов — на основе mhtml-технологии. Другими словами, на данный момент мы имеем полный спектр решений для всех современных браузеров (99% процентов всех используемых браузеров). Но, как всегда, "ложку дегтя" подкидывает Microsoft. Во время тестирования найдена ошибка mhtml-технологии в Vista IE7 — а именно, браузер IE7 в ОС Vista при кэшировании mhtml-файла отказывается показывать изображения (это связано с малодокументированными проблемами безопасности при использовании mhtml в Vista IE7). Если сделать файл некэшируемым, то все работает, как и должно работать, но в случае с кэшированием фоновые изображения не отображаются.


В общем, Microsoft все же сделал так, чтобы "цепь разорвалась". На текущий момент для браузера IE7 в ОС Vista реализация DURIS работает не совсем так, как задумывалось изначально. В подключение стилей внедрен алгоритм проверки IE7 Vista и в случае обнаружения такового фоновые картинки подключаются стандартным путем. Статистика показывает, что пользователей, которые используют IE7 под Vista, около 5% процентов. В любом случае, мы уже знаем, что в IE8 нормально реализована data^RI-технология.

4.4.5. Основные достоинства

Выделим два наиболее важных достоинства использования современного подхода генерации CSS-спрайтов.

  • Все фоновые изображения, вынесенные в дополнительный файл стилей, загружаются за одно подключение к серверу — это обстоятельство позволяет уменьшить нагрузку на сервер и ускорить отображение фоновых изображений.
  • Сборка конечного файла CSS-спрайтов производится автоматически — это позволяет безболезненно проводить модернизацию изображений.

4.4.6. Что имеем

На сегодняшний день мы имеем стабильную бета-версию DURIS, которая отрабатывает все передаваемые ей CSS-файлы. Отрабатываются также специфические правила, такие как filter:AlphaImageLoader, !important. Ядро DURIS разработано на языке Java и является самодостаточным (т. е. не зависит от сайта). Предполагается, что после получения релиз-кандидата исходный код ядра будет выложен в открытый доступ под OpenSource-лицензией. Ядро работает с командной строки наподобие того, как работает YUI Compressor. Это позволит удобно интегрировать автоматическую генерацию CSS-спрайтов в свои проекты. Кто программирует на Java, при желании сможет напрямую вызывать методы ядра DURIS.

4.4.7. Итого

Разработанный метод/алгоритм автоматической генерации CSS-спрай-тов основе data:URI уникален в своем роде и не имеет мировых аналогов. На сайте выложен FAQ (http://duris.ru/faq/), в котором детально описано, что и как работает. Если что не понятно — задаем вопросы в комментариях.

В роли главного разработчика данного решения выступил Руслан Си-ницкий (aka sirus, http://fullajax/#:developers).

4.4.8. Будущее

При появлении поддержки в IE8 схемы data:URI (стоит все же помнить об ограничении в 32 Кб, http://msdn.microsoft.com/en-us/library/cc848897%28VS.85%29.aspx) разработанный подход становится довольно перспективным, теперь все современные браузеры поддерживают такие спрайты.

Детально ознакомиться с принципами генерации и подключения data:URI CSS-спрайтов можно в разделе FAQ (http://duris.ru/faq/). Если у вас возникли вопросы или предложения по работе сайта или алгоритма в целом, вы можете оставить свои пожелания на этом сайте в форме обратной связи.

Стоит также понимать, что наиболее эффективные методы клиентской оптимизации будут использовать комбинированные решения (как, например, это реализовано в Web Optimizer). Часть фоновых изображений, которые сложно или нерационально "склеивать" в CSS Sprites и которые невелики по размеру, мы можем включить прямо в CSS-файл. Размер его при этом увеличится незначительно.

Большие же изображения (больше 24 Кб) мы не можем включать из принципов кроссбраузерности, они могут формировать CSS Sprites и этим не только уменьшать общее время загрузки, но и формировать наиболее оптимальную визуальную скорость загрузки сайта у конечного пользователя. При этом часть картинок (включенных через комбинированный data:URI) появится сразу же, а часть (включенных через CSS Sprites) — через некоторое время, так как они будут представлены отдельными файлами.

< Лекция 4 || Лекция 5: 12345 || Лекция 6 >
Ольга Артёмова
Ольга Артёмова

Доброго времени суток!

Прошла курс, но почему-то диплом получить не могу, хотя курс значится завершенным, хотя обязательные два модуля пройдены. Как решить эту проблему?

Сертификация: оптимизация и продвижение web-сайтов.

Ярославй Грива
Ярославй Грива
Россия, г. Санкт-Петербург
Ёдгор Латипов
Ёдгор Латипов
Таджикистан, Кургантепа