Как быстрее реагировать на взаимодействие с пользователем.
Я нажал, но ничего не произошло! Почему я не могу взаимодействовать с этой страницей? 😢
Первая отрисовка контента (FCP) и Самая большая отрисовка контента (LCP) — это метрики, которые измеряют время, необходимое для визуального рендеринга (отрисовки) контента на странице. Хотя это и важно, время отрисовки не учитывает скорость реагирования на нагрузку или то, как быстро страница реагирует на взаимодействие с пользователем.
Задержка первого ввода (FID) — это метрика Core Web Vitals , которая фиксирует первое впечатление пользователя об интерактивности и отзывчивости сайта. Он измеряет время с момента первого взаимодействия пользователя со страницей до момента, когда браузер фактически сможет отреагировать на это взаимодействие. FID является полевым показателем и не может быть смоделирован в лабораторных условиях. Для измерения задержки ответа требуется реальное взаимодействие с пользователем .
Чтобы помочь спрогнозировать FID в лаборатории , мы рекомендуем общее время блокировки (TBT) . Они измеряют разные вещи, но улучшения TBT обычно соответствуют улучшениям FID.
Основная причина плохого FID — интенсивное выполнение JavaScript . Оптимизация синтаксического анализа, компиляции и выполнения JavaScript на вашей веб-странице напрямую уменьшит FID.
Тяжелое выполнение JavaScript
Браузер не может реагировать на большую часть пользовательского ввода во время выполнения JavaScript в основном потоке. Другими словами, браузер не может реагировать на действия пользователя, пока основной поток занят. Чтобы улучшить это:
- Разбивайте длинные задачи
- Оптимизируйте свою страницу для обеспечения готовности к взаимодействию
- Используйте веб-воркер
- Сократите время выполнения JavaScript
Разбивайте длинные задачи
Если вы уже пытались уменьшить объем JavaScript, загружаемого на одну страницу, может быть полезно разбить долго выполняющийся код на более мелкие асинхронные задачи .
Длинные задачи — это периоды выполнения JavaScript, когда пользователи могут обнаружить, что ваш пользовательский интерфейс не отвечает. Любой фрагмент кода, блокирующий основной поток на 50 мс и более, можно охарактеризовать как Длинную задачу. Длинные задачи — признак потенциального раздувания JavaScript (загрузка и выполнение большего количества задач, чем может понадобиться пользователю прямо сейчас). Разделение длинных задач может уменьшить задержку ввода на вашем сайте.
![Длинные задачи в Chrome DevTools](https://web.dev/static/articles/optimize-fid/image/long-tasks-chrome-devtoo-490129b8a172d.png?authuser=5&hl=ru)
FID должен заметно улучшиться по мере того, как вы будете применять лучшие практики, такие как разделение кода и разбиение длинных задач. Хотя TBT не является метрикой на местах, он полезен для проверки прогресса на пути к конечному улучшению как времени взаимодействия (TTI), так и FID.
Оптимизируйте свою страницу для обеспечения готовности к взаимодействию
Существует ряд распространенных причин плохих показателей FID и TBT в веб-приложениях, которые в значительной степени полагаются на JavaScript:
Выполнение собственного скрипта может задержать готовность к взаимодействию.
- Раздувание размера JavaScript, длительное время выполнения и неэффективное разбиение на фрагменты могут замедлить скорость реакции страницы на ввод пользователя и повлиять на FID, TBT и TTI. Прогрессивная загрузка кода и функций может помочь распределить эту работу и повысить готовность к взаимодействию.
- Приложения, отображаемые на стороне сервера, могут выглядеть так, как будто они быстро рисуют пиксели на экране, но остерегайтесь того, что взаимодействие с пользователем блокируется выполнением больших сценариев (например, повторная гидратация для подключения прослушивателей событий). Это может занять несколько сотен миллисекунд, а иногда даже секунд, если используется разделение кода на основе маршрутов. Рассмотрите возможность переноса большей логики на серверную сторону или статической генерации большего количества контента во время сборки.
Ниже приведены показатели TBT до и после оптимизации загрузки собственных сценариев для приложения. Убрав дорогостоящую загрузку (и выполнение) скриптов для второстепенного компонента с критического пути, пользователи смогли гораздо быстрее взаимодействовать со страницей.
Получение данных может повлиять на многие аспекты готовности к взаимодействию.
- Ожидание водопада каскадных выборок (например, JavaScript и выборок данных для компонентов) может повлиять на задержку взаимодействия. Стремитесь свести к минимуму зависимость от каскадной выборки данных.
- Большие встроенные хранилища данных могут увеличить время анализа HTML и повлиять как на показатели рисования, так и на взаимодействие. Стремитесь свести к минимуму объем данных, требующих постобработки на стороне клиента.
Выполнение стороннего скрипта также может задерживать задержку взаимодействия.
- Многие сайты включают сторонние теги и аналитику, которые могут привести к перегрузке сети и периодическому прекращению ответа основного потока, что влияет на задержку взаимодействия. Изучите возможность загрузки стороннего кода по требованию (например, не загружайте рекламу, расположенную ниже сгиба, пока она не будет прокручена ближе к области просмотра).
- В некоторых случаях сторонние сценарии могут вытеснять собственные с точки зрения приоритета и пропускной способности в основном потоке, что также задерживает то, как скоро страница будет готова к взаимодействию. Попытайтесь в первую очередь расставить приоритеты при загрузке того, что, по вашему мнению, представляет наибольшую ценность для пользователей.
Используйте веб-воркер
Заблокированный основной поток является одной из основных причин задержки ввода. Веб-воркеры позволяют запускать JavaScript в фоновом потоке. Перемещение операций, не связанных с пользовательским интерфейсом, в отдельный рабочий поток может сократить время блокировки основного потока и, следовательно, улучшить FID.
Рассмотрите возможность использования следующих библиотек, чтобы упростить использование веб-воркеров на вашем сайте:
- Comlink : вспомогательная библиотека, которая абстрагирует
postMessage
и упрощает ее использование. - Workway : экспортер веб-работников общего назначения.
- Workerize : переместите модуль в веб-воркер.
Сократите время выполнения JavaScript
Ограничение количества JavaScript на вашей странице сокращает время, которое браузер тратит на выполнение кода JavaScript. Это ускоряет реакцию браузера на любое взаимодействие с пользователем.
Чтобы уменьшить количество JavaScript, выполняемого на вашей странице:
- Отложить неиспользуемый JavaScript
- Минимизируйте неиспользуемые полифилы
Отложить неиспользуемый JavaScript
По умолчанию весь JavaScript блокирует рендеринг. Когда браузер встречает тег сценария, который ссылается на внешний файл JavaScript, он должен приостановить выполнение и загрузить, проанализировать, скомпилировать и выполнить этот JavaScript. Поэтому вам следует загружать только тот код, который необходим для страницы или отвечает на ввод пользователя.
Вкладка «Покрытие» в 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>
Если нет особых причин не делать этого, все сторонние скрипты по умолчанию должны загружаться либо с defer
, либо async
режимом.
Минимизируйте неиспользуемые полифилы
Если вы пишете свой код с использованием современного синтаксиса JavaScript и ссылаетесь на API современных браузеров, вам нужно будет транспилировать его и включить полифилы, чтобы он работал в старых браузерах.
Одна из основных проблем с производительностью при включении полифилов и транспилированного кода на ваш сайт заключается в том, что новым браузерам не придется загружать их, если они им не нужны. Чтобы сократить размер JavaScript вашего приложения, максимально сведите к минимуму неиспользуемые полифилы и ограничьте их использование средами, где они необходимы.
Чтобы оптимизировать использование полифилов на вашем сайте:
- Если вы используете Babel в качестве транспилятора, используйте
@babel/preset-env
чтобы включать только полифилы, необходимые для браузеров, на которые вы планируете ориентироваться. В Babel 7.9 включите опциюbugfixes
, чтобы еще больше сократить количество ненужных полифилов. Используйте шаблон модуль/номодуль для доставки двух отдельных пакетов (
@babel/preset-env
также поддерживает это черезtarget.esmodules
).<script type="module" src="modern.js"></script> <script nomodule src="legacy.js" defer></script>
Многие новые функции ECMAScript, скомпилированные с помощью Babel, уже поддерживаются в средах, поддерживающих модули JavaScript. Таким образом, делая это, вы упрощаете процесс, гарантируя, что только транспилированный код используется для браузеров, которым он действительно нужен.
Инструменты разработчика
Для измерения и отладки FID доступен ряд инструментов:
Lighthouse 6.0 не включает поддержку FID, поскольку это метрика поля. Однако общее время блокировки (TBT) можно использовать в качестве прокси. Оптимизации, улучшающие ТБТ, должны также улучшить FID на местах.
Отчет об опыте пользователя Chrome предоставляет реальные значения FID, агрегированные на уровне источника.
Выражаем благодарность Филипу Уолтону, Кейси Баскес, Илье Григорику и Энни Салливан за их обзоры.