С марта 2024 года Interaction to Next Paint — одна из трёх Core Web Vitals, она заменила FID. Разница принципиальная: FID измерял только задержку первого взаимодействия, а INP смотрит на все клики, касания и нажатия клавиш за весь визит — и показывает одно из худших.
Что именно измеряет INP
Каждое взаимодействие состоит из трёх частей. Медленной может быть любая, поэтому сначала нужно понять, какая именно.
- Input delay — время, пока браузер вообще начнёт обрабатывать событие, потому что главный поток занят чем-то другим.
- Processing time — время выполнения ваших обработчиков.
- Presentation delay — пересчёт стилей, layout и отрисовка следующего кадра.
| Оценка | INP (75-й перцентиль) |
|---|---|
| Хорошо | ≤ 200 мс |
| Нужно улучшить | 200–500 мс |
| Плохо | > 500 мс |
Измеряйте в поле, а не только в лаборатории
Lighthouse не кликает за пользователя, поэтому настоящий INP не покажет. Нужны данные реальных сессий. Проще всего — библиотека web-vitals со сборкой attribution, которая сразу говорит, какой элемент и какая фаза подвели.
import { onINP } from 'web-vitals/attribution';
onINP(({ value, attribution }) => {
const { interactionTarget, inputDelay, processingDuration, presentationDelay } = attribution;
navigator.sendBeacon('/vitals', JSON.stringify({
value, interactionTarget, inputDelay, processingDuration, presentationDelay,
}));
});
Через неделю сбора обычно видно, что проблему создают несколько конкретных элементов: фильтр в магазине, кнопка «в корзину», меню на телефоне.
Разбейте длинные задачи
Самая частая причина плохого INP — обработчик, который делает всё сразу: обновляет состояние, пересчитывает список, отправляет аналитику. Браузер не может отрисовать кадр, пока это не закончится. Решение: сразу сделать то, что видно, а остальное отдать по частям.
function yieldToMain() {
if ('scheduler' in window && 'yield' in scheduler) return scheduler.yield();
return new Promise((resolve) => setTimeout(resolve, 0));
}
button.addEventListener('click', async () => {
showSpinner(); // пользователь сразу видит реакцию
await yieldToMain();
applyFilters();
await yieldToMain();
sendAnalytics();
});
Совет Панель Performance в Chrome DevTools теперь показывает взаимодействия на отдельной дорожке и помечает те, что длиннее 200 мс. Запишите клик и ищите красные треугольники.
Быстрые победы
- Отложите сторонние скрипты (чат, тепловые карты) до момента после взаимодействия или простоя.
- Уменьшите DOM — тысячи узлов делают каждый layout дороже.
- Используйте
content-visibility: autoдля секций ниже первого экрана. - Не читайте размеры (
offsetHeight) сразу после изменения стилей в цикле — это вызывает синхронный layout.
INP редко исправляется одной правкой. Но обычно хватает трёх-четырёх точных изменений в самых кликаемых местах, чтобы опуститься ниже 200 мс.
