« Объединение встроенных изображений в ваши (кэшированные) таблицы стилей — это способ уменьшить HTTP-запросы и избежать увеличения размера ваших страниц… 40-60% ежедневных посетителей вашего сайта приходят с пустым кешем. Создание быстрой страницы для этих новых посетителей является ключом к улучшению взаимодействия с пользователем ».
Формат URI данных указан как
1
|
data:[<mime type >][;charset=<charset>][; base64 ],<encoded data> |
Нас интересуют только изображения, так что типы пантомимы могут быть, например, image / gif, image / jpeg или image / png. Кодировка должна быть опущена для изображений. Кодировка обозначается как; base64. Один пример правильного URI данных:
1
2
3
|
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA AAAFCAYAAACNbyblAAAAHElEQVQI12P4 //8/w38GIAXDIBKE0DHxgljNBAAO 9TXL0Y4OHwAAAABJRU5ErkJggg== " alt=" Red dot"> |
Фрагменты HTML со встроенными изображениями, как в примере выше, не очень интересны, потому что они не кэшируются. URI данных в CSS-файлах (таблицы стилей) кэшируются вместе с CSS-файлами, что дает преимущества. Некоторые преимущества, описывающие в Википедии:
- HTTP-запрос и трафик заголовка не требуются для встроенных данных, поэтому URI данных потребляют меньшую полосу пропускания всякий раз, когда накладные расходы на кодирование встроенного содержимого в виде URI данных меньше, чем накладные расходы HTTP. Например, требуемое кодирование base64 для изображения длиной 600 байтов должно составлять 800 байтов, поэтому, если HTTP-запрос требует более 200 байтов служебной информации, URI данных будет более эффективным.
- Для передачи множества небольших файлов (менее нескольких килобайт каждый) это может быть быстрее. TCP-передачи обычно начинаются медленно. Если для каждого файла требуется новое TCP-соединение, скорость передачи ограничивается временем прохождения сигнала в обоих направлениях, а не доступной пропускной способностью. Использование поддержки активности HTTP улучшает ситуацию, но не может полностью устранить узкое место.
- При просмотре защищенного веб-сайта HTTPS веб-браузеры обычно требуют, чтобы все элементы веб-страницы загружались через защищенные соединения, или пользователь будет уведомлен об уменьшении безопасности из-за сочетания безопасных и незащищенных элементов. На плохо настроенных серверах HTTPS-запросы имеют значительные издержки по сравнению с обычными HTTP-запросами, поэтому встраивание данных в URI данных в этом случае может повысить скорость.
- Веб-браузеры обычно настроены на выполнение только определенного количества (часто двух) одновременных HTTP-соединений с доменом, поэтому встроенные данные освобождают соединение для загрузки другого контента.
Кроме того, URI данных лучше, чем спрайты. Изображения, организованные в виде CSS-спрайтов (многие маленькие изображения объединены в один большой), сложно поддерживать. Расходы на обслуживание высоки. Представьте себе, вы хотите изменить несколько небольших изображений в спрайте, их положение, размер, цвет или что-то еще. Ну, есть инструменты, позволяющие генерировать спрайты, но последующие изменения не легки. Особенно изменения в размерах вызывают смещение всех позиций и множество CSS изменений. И не забывайте — спрайту по-прежнему требуется один HTTP-запрос :-).
Какие браузеры поддерживают URI данных? URI данных поддерживаются для всех современных браузеров: на основе Gecko (Firefox, SeaMonkey, Camino и т. Д.), На основе WebKit (Safari, Google Chrome), Opera, Konqueror, Internet Explorer 8 и выше. Для Internet Explorer 8 URI данных должны быть меньше 32 КБ. Internet Explorer 9 не имеет этого ограничения 32 КБ. В версиях IE 5-7 отсутствует поддержка URI данных, но есть MHTML — когда вам нужны URI данных в IE7 и ниже.
Существуют ли инструменты, помогающие автоматически встраивать URI данных? Да, есть несколько инструментов. Самым популярным является инструмент командной строки CSSEmbed . Особенно если вам нужно поддерживать старые версии IE, вы можете использовать этот инструмент командной строки, который может работать с MHTML. Плагин Maven для оптимизации веб-ресурсов , который является частью проекта PrimeFaces Extensions , теперь также поддерживает URI данных. Плагин позволяет встраивать URI данных для ссылочных изображений в таблицы стилей во время сборки. Этот плагин Maven не поддерживает MHTML. Это проблематично, потому что вам нужно включать CSS-файлы с условными комментариями отдельно — для IE7 и ниже и для всех других браузеров. Как работает преобразование в URI данных?
- Плагин читает содержимое файлов CSS. Специальная реализация java.io.Reader ищет токены # {resource […]} в файлах CSS. Это синтаксис для ссылок на изображения в JSF 2. Токен должен начинаться с # {resource [и заканчиваться]]. Содержимое внутри содержит путь к изображению в синтаксисе JSF. Теоретически мы также можем поддерживать другие токены (они настраиваются), но нам не нужна такая поддержка 🙂 Примеры:
1234567
.ui-icon-logosmall {
background-image: url(
"#{resource['images/logosmall.gif']}"
) !important;
}
.ui-icon-aristo {
background-image: url(
"#{resource['images:themeswitcher/aristo.png']}"
) !important;
}
- На следующем шаге ресурс изображения для каждого фонового изображения локализуется. Каталоги изображений определяются в соответствии со спецификацией JSF 2 и подходят для WAR, а также для проектов JAR. Это $ {project.basedir} / src / main / webapp / resources и $ {project.basedir} / src / main / resources / META-INF / resources. Каждое изображение пытаются найти в этих каталогах.
- Если изображение не найдено в указанных каталогах, оно не преобразуется. В противном случае изображение кодируется в строку base64. Кодирование выполняется только в том случае, если строка URI данных меньше 32 КБ для поддержки браузера IE8. Изображения больше этой суммы не преобразуются. URI данных выглядит так
1234567
.ui-icon-logosmall {
background-image: url(
"data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgA ... ASUVORK5CYII="
) !important;
}
.ui-icon-aristo {
background-image: url(
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA ... BJRU5ErkJggg=="
) !important;
}
Конфигурация в pom.xml проста. Чтобы включить эту функцию, установите для флага useDataUri значение true. Пример:
01
02
03
04
05
06
07
08
09
10
11
12
|
< plugin > < groupId >org.primefaces.extensions</ groupId > < artifactId >resources-optimizer-maven-plugin</ artifactId > < configuration > < useDataUri >true</ useDataUri > < resourcesSets > < resourcesSet > < inputDir >${project.build.directory}/webapp-resources</ inputDir > </ resourcesSet > </ resourcesSets > </ configuration > </ plugin > |
Достаточно теории. Теперь я опишу часть практики. Я покажу некоторые измерения, снимки экрана и дам советы, какими должны быть большие изображения, где должен быть размещен CSS, каков размер файла CSS с URI данных и может ли здесь помочь фильтр GZIP. Читать дальше.
Первый вопрос: стоит ли помещать URI данных в таблицы стилей? Да, это того стоит. Во-первых, я хотел бы указать вам на эту замечательную статью « URI данных для изображений CSS: больше тестов, больше вопросов », где вы можете попробовать протестировать все три сценария для вашего местоположения. Задержка зависит от вашего местоположения. Но вы можете увидеть тенденцию, что веб-страница, содержащая URI данных, загружается быстрее. Мы можем увидеть один из основных приемов для достижения лучшей производительности с помощью URI данных:
Разделите ваш CSS на два файла — один с основными данными, а другой только с URI данных, и поместите второй в нижний колонтитул. «В нижнем колонтитуле» означает близкий к тегу тела HTML. Рендеринг страницы происходит быстрее, чем из-за прогрессивного рендеринга Во второй статье вы можете увидеть, что этот метод действительно ускоряет рендеринг страниц. Таблица стилей в нижнем колонтитуле обеспечивает приятный эффект загрузки больших изображений параллельно с таблицей стилей URI данных. Почему? Что ж, браузер считает, что содержимое, размещенное в нижнем колонтитуле, не может влиять на структуру страницы над включенными файлами и не блокирует загрузку ресурсов. Я также читал, что в этом случае все браузеры (кроме старых версий IE) отображают страницу немедленно, не дожидаясь загрузки CSS с URI данных. Насколько я знаю, то же самое относится и к файлам JavaScript. Действительно ли вообще помещать CSS-файлы в нижний колонтитул страницы? Ну, это не рекомендуется в спецификации HTML. Но это действительно на практике и совсем не плохо в особых случаях. Существует интересная дискуссия о Stackoverflow » Насколько плохо помещать CSS- вставку в середине тела? »
Второй совет — использовать URI данных для небольших изображений размером до 1-2 КБ. Не стоит использовать данные URI для больших изображений. Большое изображение имеет очень длинную строку URI данных (строку в кодировке base64), что может увеличить размер файла CSS. Файлы большого размера могут блокировать загрузку других файлов. Помните, что браузеры имеют ограничения на соединение. Обычно они могут открыть 2-8 соединений к одному домену. Это означает, что одновременно можно загружать только 2-8 файлов. После прочтения некоторых комментариев в Интернете я получил подтверждение о моем предположении с изображениями 1-2 КБ.
Мы можем смягчить это поведение, используя фильтр GZIP. Фильтр GZIP уменьшает размер ресурсов. Я читал, что иногда размер изображения, закодированного как URI данных, даже меньше, чем размер исходного изображения. Фильтр GZIP применяется к веб-ресурсам, таким как файлы CSS, JavaScript и (X) HTML. Но не рекомендуется применять его к изображениям и файлам PDF, например. Таким образом, не закодированные изображения не проходят через файлер, а файлы CSS проходят. В 99% случаев, если вы распакуете свой CSS-файл, получающийся в результате размер будет примерно таким же, как и обычный URL-адрес изображения! И это был третий совет — используйте фильтр GZIP.
Я хотел бы показать результаты моего теста. Моя тестовая среда: Firefox 11 на Kubuntu Oneiric. Я подготовил демонстрацию расширений PrimeFaces с 31 изображением, которое я добавил на стартовую страницу. На этих изображениях отображаются значки небольших тем в формате PNG. Каждое изображение имеет одинаковый размер 30 х 27 пикселей. Размеры в килобайтах лежат в диапазоне 1,0 — 4,6 КБ. Файл CSS без URI данных составлял 4,8 КБ, а URI данных — 91,6 КБ. Кстати, CSS-файлы вполне нормально включались в раздел HTML-заголовка. Я развернул витрины с и без URI данных на моем VPS с сервером Jetty 8. Сначала без файла GZIP. Я очистил кеш браузера и открыл Firebug для каждой витрины. Вот результаты:
Без данных URI:
65 запросов. Время загрузки страницы 3,84 с (загрузка: 4,14 с).
Это означает, что событие готовности документа произошло после 3.84 сек. и окно загрузки после 4.14 сек. Последующие обращения к той же странице (ресурсы были получены из кэша браузера) заняли 577 мс, 571 мс, 523 мс,…
С URI данных:
34 запроса. Время загрузки страницы 3,15 с (загрузка: 3,33 с).
Это означает, что меньше запросов (помните, 31 встроенных изображений), событие готовности документа произошло после 3.15 сек. и окно загрузки после 3.33 сек. Последующие обращения к той же странице (ресурсы были получены из кэша браузера) заняли 513 мс, 529 мс, 499 мс,…
Нет большой разницы для последующих звонков (обновление страницы), но есть существенная разница при первом посещении. Особенно событие onload происходит быстрее с URI данных. Неудивительно. Изображения загружаются после того, как документ готов. Поскольку они не могут быть загружены параллельно (количество открытых соединений ограничено), они блокируются. Я сделал несколько фотографий из Google Chrome Web Inspector. Ниже вы можете увидеть время для изображения (vader.png) для первого (обычного) случая без URI данных.
И второй случай для того же изображения закодирован как URI данных.
Вы видите на второй картинке, что нет никакой блокировки вообще. Тесты с фильтром GZIP не оказали большого влияния в моем случае (не знаю почему, может быть, у меня не так много ресурсов). Среднее время после пары тестов с пустым кешем:
Без данных URI:
65 запросов. Время загрузки страницы 3,18 с (загрузка: 3,81 с).
С URI данных:
34 запроса. Время загрузки страницы 3,03 с (загрузка: 3,19 с).
Справка: высокопроизводительные веб-приложения. Используйте данные URI. Практика , высокопроизводительные веб-приложения. Используйте данные URI. Теория от нашего партнера JCG Олега Вараксина в блоге Мысли о разработке программного обеспечения .