Оптимизация CSS для более быстрой загрузки страницы

Оптимизация CSS для более быстрой загрузки страницы

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

Почему время загрузки важно?

Потому что время — деньги. Эта пословица особенно актуальна для времени загрузки веб-страницы. Время загрузки вашей страницы напрямую влияет на прибыль. Люди с большей вероятностью купят что-то в быстром интернет-магазине, чем в медленном. Согласно исследованию, миллисекунды дают миллионы – ускорение на 0,1 секунды на мобильных сайтах, увеличивая конверсию на 10,1% и стоимость заказа на сайтах путешествий на 1,9%. Это могут быть большие деньги.

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

ПРИМЕЧАНИЕ. Есть и другие исследования, подтверждающие эту закономерность. Я использовал пример из упомянутого выше исследования, потому что это самый последний, который мне удалось найти.

Как CSS влияет на время загрузки

Чтобы увидеть, как CSS влияет на время загрузки веб-страницы, мы сначала должны знать, как браузер преобразует HTML-документ в функциональную веб-страницу.

Во-первых, он должен загрузить HTML-документ и проанализировать его для создания DOM (объектной модели документа). Каждый раз, когда он встречает какой-либо внешний ресурс (CSS, JS, изображения и т. д.), Он назначает ему приоритет загрузки и инициирует его загрузку. Приоритеты важны, потому что некоторые ресурсы критичны для визуализации страницы (например, основная таблица стилей и файлы JS), в то время как другие могут быть менее важными (например, изображения или таблицы стилей для других типов мультимедиа).

HTTP / 1.1 также имеет жесткое ограничение на количество подключений на один домен (точное количество зависит от браузера, в наши дни обычно 6). Поэтому, если вы хотите загрузить большое количество ресурсов из одного домена, некоторые из них должны ждать в очереди, пока не закончат загрузку ресурсов с более высоким приоритетом. Поэтому при использовании HTTP / 1.1 сохраняйте небольшое количество запросов. HTTP / 2 не имеет этого ограничения, но пока не все сайты используют HTTP / 2.

В случае CSS этот приоритет обычно высок, потому что таблицы стилей необходимы для создания CSSOM (объектной модели CSS). Чтобы отобразить веб-страницу, браузер должен создавать как DOM, так и CSSOM. Без этого браузер не будет отображать пиксели на экране. Причина этого заключается в том, что стили определяют внешний вид страницы, и отрисовка страницы без них была бы пустой тратой вычислительных мощностей и приводила бы к плохому пользовательскому интерфейсу. Только когда в браузере доступны и DOM, и CSSOM, он может создать дерево рендеринга, объединив их, и начать рендеринг экрана. Короче говоря, CSS не загружается, страница не отображается.

Как видите, CSS оказывает огромное влияние на время загрузки веб-страницы. Когда мы говорим о CSS, есть две основные области, влияющие на время загрузки веб-страницы:

Размер файла CSS и общий объем CSS на странице (количество файлов). Для загрузки слишком больших файлов CSS потребуется больше времени, и, следовательно, для рендеринга всей страницы потребуется гораздо больше времени (сначала нужно дождаться загрузки этого большого CSS).

Когда и как мы запускаем и загружаем CSS. Вам нужно как можно скорее загрузить стили.

Давайте рассмотрим подробно, как мы можем это улучшить.

Ограничьте размер таблицы стилей

TL; DR: правильно настройте инструменты, чтобы по возможности использовать современный код.

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

Я бы посоветовал проверить код результата на предмет ненужного раздутия. Особенно, если вы используете PostCSS с несколькими плагинами. В моем случае у меня был CSS со сгенерированными резервными вариантами для переменных CSS и с префиксами для старого синтаксиса flexbox. Это может показаться тривиальной проблемой с очень небольшим эффектом, но в результате экономия составила около 3 КБ для небольшой таблицы стилей, такой как моя. Я думаю, что это большое улучшение при очень небольших усилиях. А для большого CSS это может иметь еще большее влияние.

старый index.css: 12.5kB (without GZip)

новый index.css: 9.2kB (without GZip, ~26.4% smaller)

Все, что мне нужно было сделать, это обновить конфигурацию списка браузеров, которая используется Autoprefixer и другими подобными инструментами для нацеливания сгенерированного кода на определенные версии браузеров. Я также немного обновил конфигурацию PostCSS. (Я также добавил плагин для объединения медиа-запросов, чтобы сэкономить дополнительное место).

Используйте критический CSS

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

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

Оптимизация CSS для более быстрой загрузки страницы

К счастью, вам не нужно решать, какие стили должны быть включены в HTML. Некоторые инструменты сделают это за вас, например Critical от Адди Османи. Имейте в виду, что эта техника предполагает компромиссы. Вам нужно найти правильный баланс между тем, что нужно включить, и размером CSS, поскольку этот метод сэкономит вам один запрос при загрузке страницы, но также сделает каждую страницу больше (и, таким образом, замедлит ее загрузку). Итак, вам нужно поэкспериментировать с этим и измерить результаты, чтобы найти лучшую настройку для своего сайта.

Таблицы стилей с отложенной загрузкой

Поскольку мы используем Критический CSS, нам нужно отложенно загружать таблицы стилей, чтобы не блокировать отображение страницы. Если вам не нужна поддержка некоторых старых браузеров, современное решение в наши дни заключается в применении обычного тега ссылки, который вы используете для таблиц стилей, но с другим типом медиа и небольшим количеством JS. Этот небольшой хитрый трюк полностью описан в посте в блоге Filament Group. Ниже вы можете увидеть фрагмент для отложенной загрузки CSS из этого поста, но я предлагаю прочитать его полностью.

<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">

ПРИМЕЧАНИЕ. Если вы используете указанный выше пакет Critical, он автоматически преобразует таблицу стилей в режим отложенной загрузки.

Вы можете включить резервный вариант, когда JS отключен. Таким образом, ваши стили будут загружаться нормально, и вы избежите нестилизованного контента, который может плохо повлиять на взаимодействие с пользователем.

<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">
<noscript> <link rel="stylesheet" href="/path/to/my.css" media="screen">
</noscript>

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

Оптимизация CSS для более быстрой загрузки страницы

Диаграмма водопада для страницы проектов без критического CSS

Оптимизация CSS для более быстрой загрузки страницы

Диаграмма водопада для страницы проектов с критическим CSS

Используйте разделение кода для таблиц стилей

У нас есть CSS со свойствами, которые нам нужны для современных браузеров, и мы используем критически важный CSS, а остальное — отложенная загрузка. Но мы, вероятно, можем немного уменьшить размер файла. В инструментах разработчика Chrome есть инструмент под названием Покрытие. Он может показать вам, какая часть файлов CSS и JS используется на текущей странице. Откройте инструменты разработчика и нажмите Ctrl+ Shift+p, чтобы открыть панель команд, и введите Coverage. Выберите параметр Показать покрытие, чтобы отобразить панель. Теперь перезагрузите страницу.

Оптимизация CSS для более быстрой загрузки страницы

Оптимизация CSS для более быстрой загрузки страницы

Почти 50% моего кода CSS не использовалось на странице. Когда мы проверяем другую страницу, мы получаем еще больше — почти 54% неиспользуемого CSS. Это много ненужного кода. И это число может быть еще больше в больших устаревших приложениях.

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

Разделение CSS на основе медиа-запросов

В этом подходе вы разбиваете большой CSS на более мелкие таблицы стилей на основе медиа-запросов (у PostCSS есть плагин для этого) и ссылаетесь на эти таблицы стилей в HTML.

<link rel="stylesheet" href="index.css" media="all" />
<link rel="stylesheet" href="mobile.css" media="(max-width:44.9375rem)" />
<link rel="stylesheet" href="table.css" media="(min-width: 45rem)" />

Имейте в виду, что этот подход не имеет особого смысла при использовании Критического CSS и отложенной загрузке таблицы стилей. Браузер загрузит все таблицы стилей независимо от того, какой медиа-запрос используется. Он будет использовать только атрибут media для определения приоритетов загрузок. Таким образом, в основном он будет загружать CSS с высоким приоритетом для активного медиа-запроса и отложенно загружать остальные таблицы стилей.

Разделение кода на основе страниц

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

Звучит довольно просто, поэтому я решил попробовать и создать скрипт node, который может делать такие вещи. Он называется CSS Split и отлично работает для сайтов, созданных с использованием генератора статических сайтов (например, Eleventy, который я использую для своего сайта). Он использует PurgeCSS для удаления неиспользуемых стилей, поэтому должен работать и с другими файлами, отличными от HTML (на основе их документации). Я не тестировал его ни на что иное, кроме HTML, поэтому, используя его таким образом, обязательно перепроверьте результаты.

Используя эту технику, я смог уменьшить размер файла запрашиваемого CSS почти на 50%. Ниже приведены некоторые статистические данные после внедрения Critical CSS и разделения кода на основе страниц:

Один index.css для всех страниц: 9.2kB (without GZip)

CSS файл для главной страницы: 5.4kB (without GZip)

CSS файл для проектов: 4.4kB (without GZip)

Оптимизация CSS для более быстрой загрузки страницы

Оптимизация CSS для более быстрой загрузки страницы

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

Разделение кода на основе компонентов

Я получил совет от Гарри Робертса. Мы также можем разделить CSS на компонентную основу и постепенно загружать CSS только для компонентов, которые мы используем на странице (футер, хэдер, контент и т. д.). Подробнее об этой хитрости вы можете прочитать в статье Гарри. Эта техника, о которой я говорю, описана в последнем разделе статьи. Но прочтите всю статью, она содержит отличную информацию об улучшении производительности сети CSS, которую я здесь не описываю (я все равно не мог бы написать лучше).

Я до сих пор не тестировал эту технику, чтобы увидеть, насколько она будет работать по сравнению с моей текущей настройкой, но она в моем списке дел. Так что следите за обновлениями в следующих статьях.

Заключение

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

Ниже вы можете увидеть некоторые окончательные результаты после обновлений. Графики показывают, какой процент страницы был отображен в какое время. Эти тесты проводились при медленном 3G-соединении, поэтому загрузка страницы занимает так много времени.

Оптимизация CSS для более быстрой загрузки страницы

Главная страница – финальное сравнение

Оптимизация CSS для более быстрой загрузки страницы

Страница проектов – финальное сравнение

Оптимизация CSS для более быстрой загрузки страницы

Одиночная статья – финальное сравнение

Спасибо, что прочитали эту статью.

Автор: Tomas Pustelnik

Источник: https://pustelto.com

Редакция: Команда webformyself.