Опубликовано: 17 августа 2018 г.
В этом руководстве правила PageSpeed Insights рассматриваются в контексте: на что следует обращать внимание при оптимизации критического пути рендеринга и почему.
Устраните блокировку рендеринга JavaScript и CSS.
Чтобы обеспечить максимально быстрое время первого рендеринга, минимизируйте и (где это возможно) исключите количество критических ресурсов на странице, минимизируйте количество загружаемых критических байтов и оптимизируйте длину критического пути.
Оптимизировать использование JavaScript
Ресурсы JavaScript по умолчанию блокируются парсером, если они не помечены как async
или не добавлены с помощью специального фрагмента JavaScript. Парсер, блокирующий JavaScript, заставляет браузер ждать CSSOM и приостанавливает построение DOM, что, в свою очередь, может значительно задержать время первого рендеринга.
Предпочитаете асинхронные ресурсы JavaScript
Асинхронные ресурсы разблокируют анализатор документов и позволяют браузеру избежать блокировки CSSOM перед выполнением сценария. Часто, если скрипт может использовать атрибут async
, это также означает, что он не обязателен для первого рендеринга. Рассмотрите возможность асинхронной загрузки сценариев после первоначального рендеринга.
Избегайте синхронных вызовов сервера
Используйте метод navigator.sendBeacon()
для ограничения данных, отправляемых XMLHttpRequests в обработчиках unload
. Поскольку многие браузеры требуют, чтобы такие запросы были синхронными, они могут замедлять переходы между страницами, иногда заметно. В следующем коде показано, как использовать navigator.sendBeacon()
для отправки данных на сервер в обработчике pagehide
, а не в обработчике unload
.
<script>
function() {
window.addEventListener('pagehide', logData, false);
function logData() {
navigator.sendBeacon(
'https://putsreq.herokuapp.com/Dt7t2QzUkG18aDTMMcop',
'Sent by a beacon!');
}
}();
</script>
Метод fetch()
обеспечивает лучший способ асинхронного запроса данных. fetch()
обрабатывает ответы, используя обещания, а не несколько обработчиков событий. В отличие от ответа на XMLHttpRequest, ответ fetch()
представляет собой объект потока. Это означает, что вызов json()
также возвращает обещание.
<script>
fetch('./api/some.json')
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
</script>
Метод fetch()
также может обрабатывать запросы POST.
<script>
fetch(url, {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: 'foo=bar&lorem=ipsum'
}).then(function() { // Additional code });
</script>
Отложить анализ JavaScript
Чтобы свести к минимуму объем работы, которую браузер должен выполнить для рендеринга страницы, отложите все второстепенные сценарии, которые не имеют решающего значения для создания видимого контента для первоначального рендеринга.
Избегайте длительного выполнения JavaScript
Длительный запуск JavaScript не позволяет браузеру создавать DOM, CSSOM и отображать страницу, поэтому отложите на потом любую логику инициализации, которая не важна для первого рендеринга. Если необходимо выполнить длинную последовательность инициализации, рассмотрите возможность разделения ее на несколько этапов, чтобы позволить браузеру обрабатывать другие события между ними.
Оптимизация использования CSS
CSS необходим для построения дерева рендеринга, а JavaScript часто блокирует CSS во время первоначального создания страницы. Убедитесь, что любой второстепенный CSS помечен как некритичный (например, запросы на печать и другие медиа-запросы), а количество критического CSS и время на его доставку как можно меньше.
Поместите CSS в заголовок документа
Укажите все ресурсы CSS как можно раньше в документе HTML, чтобы браузер мог обнаружить теги <link>
и как можно скорее отправить запрос CSS.
Избегайте импорта CSS
Директива CSS import ( @import
) позволяет одной таблице стилей импортировать правила из другого файла таблицы стилей. Однако избегайте этих директив, поскольку они вводят дополнительные обходы критического пути: импортированные ресурсы CSS обнаруживаются только после того, как таблица стилей CSS с самим правилом @import
получена и проанализирована.
Встроенный CSS для блокировки рендеринга
Для достижения максимальной производительности вы можете рассмотреть возможность встраивания критического CSS непосредственно в HTML-документ. Это исключает дополнительные обходы критического пути и, если все сделано правильно, может обеспечить длину критического пути «один туда и обратно», где только HTML является блокирующим ресурсом.