Loading...

Оптимизация FID (First Input Delay)


First Contentful Paint (FCP) и Largest Contentful Paint (LCP) - это метрики, которые измеряют время, необходимое для визуального отображения (отрисовки) контента на странице. Хотя это важно, однако, время отрисовки не учитывает реакцию на загрузку: или как быстро страница реагирует на взаимодействие с пользователем.

Первая задержка ввода (FID) - это метрика Core Web Vitals, которая фиксирует первое впечатление пользователя об интерактивности и отзывчивости сайта. Она измеряет время с момента, когда пользователь впервые взаимодействует со страницей, до времени, когда браузер действительно способен ответить на это взаимодействие. FID является метрикой, которая не может быть смоделирована в лабораторной среде. Для измерения задержки ответа требуется реальное взаимодействие с пользователем.

Чтобы помочь эмулировать FID в лаборатории, мы рекомендуем использовать общее время блокировки (TBT). Они измеряют разные вещи, но улучшения в TBT обычно соответствуют улучшениям в FID.

Основной причиной плохого FID является выполнение тяжелых скриптов JavaScript. Оптимизация компиляции и выполнения JavaScript на вашей веб-странице напрямую сократит FID.

Выполнение тяжелых скриптов JavaScript.

Браузер не может отвечать на большинство пользовательских вводимых данных, пока он выполняет JavaScript в основном потоке. Другими словами, браузер не может реагировать на взаимодействие с пользователем, пока основной поток занят. Чтобы улучшить это, необходимо:

     - Сократить время выполнения JavaScript.
     - Разбить выполнение длинных задач.
     - Оптимизация страниц для готовности к первому взаимодействию.
     - Использование web worker.

Как сократить время выполнения JavaScript.

Ограничение количества JavaScript на вашей странице уменьшает количество времени, которое браузер должен тратить на разбор, компиляцию и выполнение кода JavaScript. Это ускоряет то, как быстро браузер может начать реагировать на любые взаимодействия с пользователем.

Чтобы уменьшить количество JavaScript, выполняемого на вашей странице:

     - Сократить и сжать файлы JavaScript
     - Отложите неиспользуемый JavaScript
     - Минимизируйте использование полифилов

Помимо минимизации JavaScript, разбиение долго выполняющегося кода на более мелкие задачи может позволить браузеру быстрее запускать обработчики ввода, что может улучшить FID.

Как сократить и сжать файлы JavaScript.

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

Terser поддерживает синтаксис ES6 + и может использоваться для минимизации современных файлов JavaScript без необходимости их переноса. Если вы используете связку модулей и хотите включить Terser в свой набор инструментов:

     - Webpack и Parcel уже используют минимизацию Terser по умолчанию в своем production.
     - Если вы используете Rollup, включите rollup-plugin-terser как плагин.

В дополнение к минимизации, сжимайте ваши ресурсы JavaScript, чтобы минимизировать их размер. Если возможно, используйте Brotli, который обеспечивает лучшие результаты сжатия, чем Gzip, и может использоваться практически во всех новых браузерах.

* Для получения дополнительной информации смотрите руководство по минимизации и сжатию полезных данных.

Как отложить неиспользуемый JavaScript.

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

На вкладке Coverage в Chrome DevTools можно указать, сколько JavaScript не используется на вашей веб-странице.

Чтобы сократить неиспользуемый JavaScript необходимо:

     - Разделить ваш скрипт на несколько частей.
     - Отложить любой некритический JavaScript, включая сторонние скрипты, используя async или defer.

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

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

import('module.js')	
.then((module) => {
// Do something with the module.
});

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

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

     - Если вы используете Webpack, Rollup или Parcel в качестве связующего модуля, воспользуйтесь их динамической поддержкой импорта.
     - Клиентские инфраструктуры, такие как React, Angular и Vue, предоставляют абстракции, облегчающие отложенную загрузку на уровне компонентов.

Помимо разделения кода, всегда используйте async или defer для скриптов, которые не нужны для критического отображения содержимого.

<script defer src=""></script>	
<script async src=""></script>

Минимизируйте неиспользуемые полифилы.

Если вы создаете свой код с использованием современного синтаксиса JavaScript и ссылаетесь на API-интерфейсы современных браузеров, вам потребуется применять полифиллы, чтобы ваш код работал в старых браузерах.

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

Для оптимизации использования полифиллов на вашем сайте:

     Если вы используете Babel в качестве транспайлера, используйте  @babel/preset-env , чтобы включить только те полифилы, которые необходимы для браузеров, для которых вы планируете поддержку. В Babel 7.9 включите опцию исправления ошибок, чтобы дополнительно сократить ненужные полифилы.

     Используйте шаблон module/nomodule для поддержки двух отдельных пакетов (@babel/preset-env также поддерживает это через target.esmodules).

<script type="module" src="modern.js"></script>	
<script nomodule src="legacy.js" defer></script>

Многие новые функции ECMAScript, скомпилированные с Babel, уже поддерживаются в средах, поддерживающих модули JavaScript. Таким образом, вы упростите процесс проверки того, что только браузер используется для браузеров, которые действительно нуждаются в нем.

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

Как разбить длинные задачи.

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

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

Chrome DevTools визуализирует длинные задачи в панели производительности "Performance Panel".

FID должен заметно улучшиться по мере того, как вы применяете лучшие практики, такие как разделение кода и разбиение ваших длинных задач. Хотя TBT не является метрикой поля, он полезен для проверки прогресса в конечном итоге к улучшению как Time To Interactive (TTI), так и FID.

Оптимизируйте свою страницу для ускорения готовности к взаимодействию.

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

    - Увеличение размера JS, большое время выполнения и неэффективное разбиение на блоки могут замедлить скорость реакции страницы на ввод данных пользователем и повлиять на показатели FID, TBT и TTI. Прогрессивная загрузка кода и функций поможет это устарнить и повысить готовность к взаимодействию, время отклика страницы.
    - Приложения на стороне сервера могут выглядеть так, как будто они быстро рисуют пиксели на экране, но остерегайтесь взаимодействия с пользователем, которое блокируется большими выполнениями скриптов. Это может занять несколько сотен миллисекунд, иногда даже секунд, если используется разделение кода на основе маршрута. Попробуйте сместить больше логики на стороне сервера или генерировать больше контента статически во время сборки.

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

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

    - Ожидание каскадных выборок (например, JS и выборок данных для компонентов) может повлиять на задержку взаимодействия. Цель - минимизировать зависимость от каскадных выборок данных.
    - Большие встроенные хранилища данных могут сократить время анализа HTML и повлиять на показатели рисования и взаимодействия. Стремитесь свести к минимуму объем данных, подлежащих последующей обработке на стороне клиента.


Выполнение сторонних скриптов также может задержать задержку взаимодействия.

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

Используйте web worker.

Блокированный основной поток является одной из основных причин задержки ввода. Web worker позволяет запускать JavaScript в фоновом потоке. Перемещение операций, не связанных с пользовательским интерфейсом, в отдельный рабочий поток может сократить время блокировки основного потока и, следовательно, улучшить FID.

Рассмотрите возможность использования следующих библиотек, чтобы упростить использование web worker на вашем сайте:

     - Comlink: вспомогательная библиотека, которая абстрагирует postMessage и упрощает использование
     - Workway: экспортер веб-работника общего назначения
     - Workerize: переместить модуль в веб-работника

Инструменты разработчика.

Доступен ряд инструментов для измерения и отладки FID:

     - Lighthouse 6.0 не включает поддержку FID, так как это метрика поля. Тем не менее, общее время блокировки (TBT) может использоваться в качестве прокси. Оптимизации, которые улучшают TBT, также должны улучшить FID на местах.


     - Chrome User Experience Report предоставляет реальные значения LCP, агрегированные на уровне источника

 

Оригинал статьи: https://web.dev/optimize-fid/

Поделиться статьей: