От автора: критический путь рендера – последовательность задач, выполняемых браузером при первом рендере страницы на экране, т.е. загрузка, обработка и конвертация HTML, CSS и JS кода в реальные пиксели и их окраска на экране.
«Оптимизация критического пути рендера – процесс минимизации времени, затраченного браузером на выполнение всех шагов последовательности, и повышение приоритета отображения контента относительно текущий действий пользователя.» Большая часть процесса относится к видимой части WordPress страницы без прокрутки окна браузера.
Эту секцию также называют Above the Fold. Для улучшения юзабилити ATF должна рендериться максимально быстро. Сделать это можно, уменьшив количество запросов на сервер. Ресурсы, необходимые для рендера ATF, называются критическими. А значит, оптимизация ATF – это минимизация влияния критических ресурсов на время первого рендера страницы.
В этой статье мы пройдем весь процесс оптимизации критического пути рендера.
Сначала я дам общий обзор задач, выполняемых браузером для рендера контента страницы
Далее я рассмотрю наиболее релевантные действия по оптимизации критического пути рендера
В конце я перечислю несколько полезных (и популярных) плагинов WordPress по оптимизации
Последовательность критического пути рендера
Последовательность шагов, выполняемых браузером для рендера страницы:
Сперва браузер загружает и парсит HTML разметку и строит DOM
Далее он загружает и обрабатывает CSS стили и строит CSSOM
Браузер соединяет DOM и CSSOM узлы, необходимые для рендера страницы в дереве рендера – древовидная структура всех видимых узлов
Далее вычисляются размеры и положение всех объектов на странице
В самом конце браузер отрисовывает пиксели на экране
DOM
Как мы писали в Critical Rendering Path Optimization guide, браузер строит объектную модель документа в 4 этапа:
Сначала браузер считывает строку байт и переводит их в отдельные символы
Затем он конвертирует строки символов в круглых скобках в токены
Эти токены конвертируются в узловые объекты
Узловые объекты связываются в древовидной структуре данных, в которой хранится HTML контента, свойства и все связи между узлами. Эта структура называется объектная модель документа.
Важно отметить, что браузер строит DOM по возрастающей. Это дает возможность ускорить рендер страницы путем создания эффективной структуры DOM.
CSSOM
Когда парсер натыкается на тег link, ведущий на внешний CSS файл, парсинг блокируется, и посылается запрос к ресурсу. После получения CSS файла браузер начинает строить дерево данных CSS узлов.
Браузер считывает строки байт файла .css и переводит их в отдельные символы
Далее он конвертирует строки символов в фигурных скобках в токены
Токены конвертируются в узловые объекты
Узловые объекты связываются с деревом данных, которое хранит CSS свойства всех узлов и связи между узлами. Эта структура называется объектная модель CSS (CSSOM).
В отличие от конструкции DOM, CSSOM не строится по возрастающей. Браузер не может использовать часть стилей, так как стили могут быть перезаписаны в том же файле. Поэтому браузер блокирует рендер, пока не получит и не распарсит весь CSS. То есть CSS блокирует рендер.
Дерево рендера
Браузер совмещает DOM и CSSOM в дерево рендера – конечное дерево, содержащее все узлы и свойства, используемые для рендера страницы на экран.
«Дерево рендера содержит лишь узлы, необходимые для рендера страницы. Поэтому невидимые узлы пропускаются.»
С помощью дерева рендера браузер вычисляет размер узлов и их положение, после чего подает эти данные в процесс отрисовки.
Макет и отрисовка
На этапе макетирования браузер вычисляет размеры и положение всех узлов дерева рендера. Браузер проходит дерево рендера от его корня и готовит блоковую модель. Эта информация используется для конвертации всех узлов дерева рендера в реальные пиксели на экране.
Оптимизация критического пути рендера
Время, затраченное на запуск всего процесса может отличаться. Оно зависит от множества факторов – размер документа, количество запросов, стили, устройство пользователя и т.д. Google рекомендует повысить приоритет видимого контента, чтобы рендер ATF проходил максимально быстро. Google дает 2 главных правила:
Структурируйте HTML, чтобы он загружал критический ATF контент в первую очередь
Снизьте количество данных, используемых в HTML, CSS и JS
Как мы писали в Google’s PageSpeed guide, если количество необходимых для рендера ATF данных превышает первичное окно загрузки (14.6Кб), потребуются дополнительные запросы на сервер. На мобильных сетях с высокими задержками это значительно снизит скорость загрузки страниц (читайте подробнее о задержках). Браузер строит DOM постепенно, поэтому мы можем снизить время, необходимо на рендер ATF, структурировав HTML таким образом, чтобы ATF загружался в первую очередь, а остальная часть страницы откладывалась на потом.
Однако оптимизация не кончается на создании эффективной структуры DOM. Это процесс улучшения и измерения, вовлекающий всю последовательность критического пути рендера. Идем дальше.
Минимизация размеров ресурсов
Мы можем уменьшить объем данных, которые браузеру необходимо загрузить, с помощью минификации, сжатия и кэширования HTML, CSS и JS ресурсов:
Минификация – процесс удаления ненужных символов (комментарии и пробелы) из исходного кода. Эти символы помогают в разработке, но они бесполезны для браузера в рендере страницы.
Сжатие – возможность веб-серверов и клиентов снижать объем передаваемых файлов для повышения скорости и лучшего использования пропускной способности
Кэширование – во всех браузерах реализован HTTP кэш. Нам необходимо убедиться, что все ответы с сервера дают нам правильные HTTP заголовки, говорящие браузеру, когда и насколько он должен кэшировать запрошенные ресурсы.
Оптимизация CSS
Мы уже знаем, что браузер обязан ждать, пока он получит и обработает CSS код, прежде чем он может отрендерить страницу (CSS блокирует рендер). Но не все CSS ресурсы блокируют рендер. CSS можно прописать область видимости при определенных условиях, и мы можем оптимизировать эту область с помощью медиа типов и медиа запросов. Если вы открыли страницу на экране, браузер пошлет запрос для медиа типа print и не будет блокировать рендер страницы для этого ресурса. Разберем следующий тег link:
1 |
<link rel="stylesheet" href="style.css" /> |
Стили по ссылке применяются при любых условиях независимо от текущего медиа типа, разрешения экрана, ориентации устройства и т.д. Это значит, что ресурс CSS всегда блокирует рендер. К счастью, мы можем послать запрос на CSS ресурс с определенными условиями. Мы можем переместить print стили в отдельный файл и использовать атрибут media, чтобы сказать браузеру, что заданные стили должны загружаться только при печати страницы. Они не блокируют рендер на экране:
1 |
<link rel="stylesheet" href="print.css" media="print" /> |
Браузер все так же загружает print.css, но уже не блокирует рендер. Более того, браузеру нужно загружать меньше данных для главного CSS файла, что поможет ускорить загрузку. На атрибут link можно задать любой медиа запрос. То есть мы можем разбить CSS на множество файлов, загружаемых по условию:
1 2 3 |
<link rel="stylesheet" href="style.css" media="screen" /> <link rel="stylesheet" href="portrait.css" media="orientation:portrait" /> <link rel="stylesheet" href="widescreen.css" media="(min-width: 42rem)" /> |
Убедитесь, что ваши стили реально необходимы для рендера страницы. Если это не так, вы можете добавить подходящее значение в атрибут media тега и разблокировать рендер.
Медиа типы и запросы могут ускорить рендер страницы, но можно сделать еще больше.
Минификация CSS – проблемы и комментарии помогают при чтении CSS кода. Удалив комментарии и пробелы из стилей, мы можем значительно уменьшить вес CSS файла.
Совмещение нескольких CSS файлов – это снизит количество HTTP запросов. Это действие в частности важно на мобильных соединениях, где высокая задержка влияет на производительность (читайте подробнее о задержках).
Инлайновый критический CSS – некоторые стили критичны и необходимы для рендера ATF страницы. Критические стили всегда необходимо помещать напрямую в HTML, чтобы избежать дополнительных HTTP запросов. Но не вставляйте в разметку большие CSS файлы. Это может потребовать дополнительных запросов для рендера ATF, что приведет к предупреждениям на PageSpeed.
Ускорение процессов макетирования и отрисовки
Время, потраченное браузером на создание макета документа, зависит от количества элементов DOM, а также от сложности этих макетов.
Если элементов DOM много, браузеру потребуется больше времени на вычисление положения и размеров всех узлов
Используйте новую Flexbox модель, она быстрее старой Flexbox и плавающих макетов
Избегайте принудительной синхронной компоновки с JS
Вычисление размера элемента и его положения занимает время и снижает производительность. Поддержание максимальной простоты DOM минимальное использование JS для предсказания процесса макетирования помогло бы браузеру ускорить рендер страницы (читайте подробнее об оптимизации макетов).
К макету строго привязан процесс отрисовки – возможно, самый долгий по времени этап в последовательности критического пути рендера. Когда бы вы не меняли раскладку элемента или любого негеометрического свойства, браузер запускает событие отрисовки. Поддержание максимальной простоты на этом этапе поможет браузеру ускорить процесс отрисовки. Например, свойство box-shadow требует вычислений, поэтому его дольше отрисовывать, чем сплошную цветную рамку.
Оптимизация процесса отрисовки может быть сложной и может потребовать работу с панелью разработчика в браузере для измерения времени, необходимого браузеру для активации каждого события. Более подробно по теме в Google’s Rendering Performance guide.
Делаем JS неблокирующим
Когда браузер натыкается на тег script, он обязан остановить парсинг HTML. Инлайновые скрипты выполняются ровно в том месте, где они добавлены в документ, и блокируют создание DOM, пока движок JS не закончит работу. Другими словами, инлайновый JS может значительно замедлить первичный рендер страницы. Однако JS также позволяет манипулировать CSS свойствами, из-за чего браузер вынужден ставить на паузу выполнение скрипта, пока не загрузится и не построится CSSOM. То есть JS блокирует парсинг.
В случае с внешними файлами JS парсер также обязан ждать, пока ресурсы не загрузятся из кэша или с удаленного сервера. Это может серьезно замедлить первый рендер страницы. Учитывая все это, что мы можем сделать для минимизации времени, необходимого браузеру на загрузку и выполнение JS?
Загружайте JS асинхронно – булев атрибут async в теге script говорит браузеру, чтобы тот выполнял скрипт асинхронно, если это возможно, не блокируя построение DOM. Браузер посылает HTTP запрос на скрипт и продолжает парсинг DOM. Скрипт также не блокирует создание CSSOM, то есть он не блокирует критический путь рендера (MDN документация с более подробным описанием атрибутов тега script)
Defer JavaScript – булев атрибут defer тега script говорит браузеру выполнять скрипт после парсинга документа, но перед запуском события DOMContentLoaded. Этот атрибут нельзя использовать, если присутствует атрибут src, т.е. скрипт инлайновый (Mozilla Hacks)
Отложите инлайновый JS – множество скриптов не манипулируют DOM или CSSOM. Поэтому они не должны блокировать парсинг. К сожалению, мы не можем использовать атрибуты async и defer для инлайновых скриптов, поэтому единственный способ загружать их после загрузки документа – перенести их вниз. Плюс в том, что инлайновые скрипты не требуют дополнительных HTTP запросов. Однако вставка скриптов, используемых на нескольких страницах приведет к избыточности кода.
Заканчиваем правилами оптимизации
Много всего, правда? Давайте вздохнем и запишем список уже описанных действий по оптимизации.
Минифицируйте, сжимайте и кэшируйте HTML, CSS и JS ресурсы
Минимизируйте использование ресурсов, блокирующих рендер (особенно CSS)
Используйте медиа запросы на тегах link
Разбейте стили и сделайте инлайновыми критические стили
Объедините несколько CSS файлов
Минимизируйте использование блокирующих парсер ресурсов (JS)
Используйте атрибут defer на тегах script
Используйте атрибут async на тегах script
Вставляйте JS напрямую в разметку и передвигайте теги script вниз документа
Теперь мы знаем основные концепции по оптимизации критического пути рендера и можем перейти к обзору популярных WP плагинов по оптимизации.
Оптимизация пути критического рендера в WordPress
Пользователи WordPress могут использовать преимущества ряда плагинов, покрывающих почти все аспекты процесса оптимизации. Вы можете установить полнофункциональный плагин или несколько плагинов за раз, каждый со своей функций по оптимизации.
«Если ваш хостинг Kinsta, вам не нужен плагин кэширования, так как на Kinsta они не нужны.»
W3 Total Cache
Один этот плагин покрывает почти все этапы процесса оптимизации критического пути рендера. На первый взгляд может показаться, что в плагине слишком много настроек, но как только вы лучше узнаете последовательность критического пути рендера, вы сможете воспользоваться преимуществами мощного набора инструментов для повышения производительности.
Список функций плагина:
HTML (посты и страницы), CSS и CSS кэшируется в память, на диск или на CDN
Кэширование новостной ленты, поисковых результатов, объектов базы данных, WP объектов и фрагментов
Минификация HTML (посты и страницы)
Минификация JS и CSS
Оптимизация JS через атрибуты async и defer
Браузерное кэширование с помощью кэш-контроля, устаревания заголовков и сущностей тегов
Сжатие HTTP (gzip)
Результаты Google PageSpeed в панели администратора WP
Это лишь несколько из множества функций W3TC. Читайте подробнее на WordPress.org plugin’s page.
WP Super Cache
WP Super Cache – еще один популярный плагин повышения производительности сайта.
В комплекте идет ряд хороших функций оптимизации, но они не такие всеобъемлющие, как в W3 Total Cache, и их могут позволить себе новички и средние пользователи.
В основном, плагин предоставляет возможность кэширования и HTTP сжатия, но в нем не хватает минификации ресурсов и оптимизации JS через атрибуты async и defer. Тем не менее, более миллиона установок говорят о том, что плагин стоит попробовать.
Autoptimize
Autoptimize имеет более 400 000 активных установок и является одним из популярнейших бесплатных плагинов для минификации.
В наборе идет возможность разделения страницы на отдельные секции, где для админки можно отдельно настроить минификацию HTML, CSS и JS.
Вы можете также объединить отдельные скрипты и стили, а также установить исключения для определенных ресурсов. Более того, Autoptimize позволяет кэшировать минифицированные ресурсы на диск или на CDN и сохранять оптимизированные файлы в виде статичных.
Оптимизация ATF
Этот плагин предоставляет мощный набор инструментов для оптимизации ATF. Инструмент для профессионалов и продвинутых пользователей, которые хотят получить 100/100 в тесте Google PageSpeed.
Некоторые из наиболее интересных возможностей:
Инструменты критического CSS:
Условная загрузка CSS
Управление критическим CSS через текстовый редактор
Gulp.js создатель критического CSS
Тесты на качество критического CSS
Оптимизация загрузки CSS:
Асинхронная загрузка CSS
Извлечение CSS из HTML
Кэширование внешних стилей
Оптимизация загрузки JS:
Асинхронная загрузка JS
Кэш localStorage
Ленивая загрузка JS
Кэширование внешних скриптов
Также плагин обеспечивает поддержка Google’s Progressive Web App и оптимизацию Google Web Font. Другие достойные внимания плагины по оптимизации:
Minify HTML Markup
WP Super Minify
Fast Velocity Minify
JCH Optimize
Более подробно описаны плагины оптимизации для WordPress в «как избавиться от блокирующего рендер JS и CSS».
Заключение
Оптимизация критического пути рендера – процесс улучшения и измерения, требующий четкого понимания всех задач, выполняемых браузером для конвертации кода в пиксели и последующего рендера страницы на экране. Более подробно изучить критический путь рендера можно в Google’s optimization guide.
Автор: Carlo Daniele
Источник: //kinsta.com/
Редакция: Команда webformyself.