awesome-everything EN
↑ Обратно к восхождению

Браузер и фронтенд-рантайм

INP: input delay, processing, presentation

Суть Interaction to Next Paint раскладывается на три части — и плохой INP только в первые секунды указывает прямо на длинную задачу гидратации, а не на обработчики событий.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 14 min

Страница результатов поиска ощущается быстрой после нескольких секунд — но в первые 3 секунды после загрузки каждый тап по кнопке занимает почти полсекунды. Сами обработчики работают 8 мс. Остальное время — не в обработчике вообще. Это ловушка INP: симптом в метрике, но причина в архитектуре.

Что измеряет INP — и что заменило FID.

Interaction to Next Paint заменила First Input Delay (FID) как Core Web Vital в марте 2024. FID измерял только задержку до старта обработчика первого ввода — она пропускала весь остальной жизненный цикл страницы и пропускала взаимодействия, которые были медленными потому что сам обработчик или результирующий рендер были тяжёлыми. INP измеряет полную задержку input-to-paint каждого клика, тапа и нажатия клавиши и репортит высокий перцентиль (фактически худший, с малой поблажкой на страницах с многими взаимодействиями). Задержка одного взаимодействия: от момента ввода пользователя до следующего кадра, видимо отражающего изменение. Хорошо: ≤200 мс на p75.

Три части задержки одного взаимодействия.

INP любого взаимодействия раскладывается на три последовательных части:

  1. Input delay — время, которое событие ввода ждёт, прежде чем его обработчик вообще сможет стартовать, потому что главный поток занят другой задачей. Это урок event loop напрямую: длинная задача в полёте задерживает ввод. Задача может быть JS, пересчётом стилей или компоновкой — чем угодно, удерживающим поток.

  2. Processing time — сколько реально работают обработчики событий. Для большинства взаимодействий на хорошо написанной странице это 10–30 мс. Если 200 мс — обработчик и есть проблема.

  3. Presentation delay — время после окончания обработчиков, пока браузер прогоняет стили, компоновку, отрисовку и композитинг и кладёт результат на экран. Обработчик, запускающий ре-рендер 5 000 узлов, имеет большой presentation delay, даже если логика обработчика была быстрой.

Плохой INP всегда одно из этих трёх. Назвать, какая часть доминирует — вся диагностика.

Разбивка задержки INP (одно взаимодействие)
Input delay
Поток занят — длинная задача в полёте
Processing time
Выполнение обработчика событий
Presentation delay
Стиль + компоновка + отрисовка + композитинг
Хороший порог INP (p75)
≤200 мс
Порог длинной задачи (держит input delay малым)
50 мс

Оптимизация каждой части.

Input delay: Перестаньте слать длинные задачи. Разбивайте работу на куски под 50 мс, дефер-ите несрочный JS, и помните, что гидратация — одна большая длинная задача рано в жизни страницы. Используйте scheduler.yield() между кусками, чтобы вернуть управление браузеру.

Processing time: Держите обработчики маленькими. Если обработчик должен делать тяжёлую работу, делайте минимум синхронно для обновления UI, затем уступайте и продолжайте — или перенесите чистое вычисление в Worker. Мощный паттерн: обновить видимое состояние синхронно и обернуть дорогую работу ниже по потоку в startTransition, чтобы отрисовка, которую ждёт пользователь, не блокировалась ею.

Presentation delay: Избегайте принудительной синхронной компоновки в обработчике (чтение layout-свойства после DOM-записи принуждает браузер немедленно перезапустить компоновку). Держите обновления DOM малыми — обработчик, перерендеривающий 5 000 узлов, имеет тяжёлый presentation delay независимо от скорости логики обработчика.

Окно гидратации — это ловушка INP.

Самый частый INP-провал на server-rendered сайте — взаимодействия, происходящие во время гидратации. Страница отрисована, пользователь видит кнопку и тапает её — но главный поток выполняет длинную задачу гидратации. Обработчик тапа может ещё не быть привязан, и даже когда привяжется, ввод стоит в очереди за остатком гидратации. INP записывает большую задержку для того раннего взаимодействия.

Паттерн характерный: INP плох только для взаимодействий в первые несколько секунд, потом нормален. Если обработчики были причиной, INP был бы плохим для всех взаимодействий. Ограниченный по времени паттерн указывает прямо на гидратацию. Каждый приём, сокращающий гидратацию — Server Components, острова, выборочная и прогрессивная гидратация, code-splitting — одновременно оптимизация INP.

Почему это работает

Long Animation Frames (LoAF) — браузерный API, сопоставляющий медленные взаимодействия со скриптами, вызвавшими их. Для кадра, в который попало медленное взаимодействие, LoAF даёт массив скриптов, выполнившихся в нём — с URL исходников и именами функций. Комбинирование LoAF с INP event timing entries (дающими разбивку input delay / processing / presentation) превращает «p75 INP 340 мс» в «функция поиска на search.js:88 — доминирующий скрипт в медленных кадрах». Именно это делает field INP-числа actionable.

Викторина

У взаимодействия INP 220 мс. Сам обработчик работает 8 мс. Где остальное время скорее всего?

Викторина

INP страницы плох только для взаимодействий в первые ~3 секунды, потом нормален. Что скорее всего причина?

Викторина

Страница результатов поиска имеет плохой INP — взаимодействия в первые 3 секунды медленные, потом нормальные. Что является основным фиксом?

Вспомните перед уходом
  1. 01
    Назовите три части задержки INP одного взаимодействия и что делает каждую высокой.
  2. 02
    Как гидратация создаёт ловушку INP, и какой характерный паттерн диагностики?
  3. 03
    Что делает scheduler.yield() для INP и когда его использовать?
Итог

INP измеряет полную задержку input-to-paint каждого взаимодействия на протяжении всего жизненного цикла страницы и репортит высокий перцентиль — это куда репрезентативнее FID, измерявшего только задержку очереди первого ввода. Задержка одного взаимодействия раскладывается на input delay (занятый поток), processing time (обработчик) и presentation delay (стоимость рендера после обработчика). Плохой INP всегда доминируется одним из трёх, и фикс разный для каждого. Характерный паттерн «только в первые секунды» — подпись гидратации: длинная задача гидратации блокирует поток, не сами обработчики. Каждый приём, сокращающий охват гидратации (Server Components, острова, code-splitting), одновременно является INP-фиксом. Хороший порог ≤200 мс на p75; поддержание каждой задачи под 50 мс — это механизм, держащий input delay малым и INP под порогом.

Связанные уроки
встречается в193
Продолжить восхождение ↑CLS: почему происходят сдвиги лейаута и как их остановить
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.