INP (Interaction to Next Paint): что это и как улучшить

INP — метрика Core Web Vitals, измеряющая отзывчивость страницы на клики и нажатия. Заменила FID в марте 2024. Норма: до 200 миллисекунд.

core-web-vitalsinpпроизводительностьseoотзывчивость

Что такое INP

INP (Interaction to Next Paint) — метрика Core Web Vitals, которая измеряет время от взаимодействия пользователя (клик, нажатие клавиши, касание экрана) до момента когда браузер отрисует следующий кадр с реакцией на это взаимодействие.

INP заменила FID (First Input Delay) в марте 2024 года. Ключевое отличие:

  • FID измерял только время обработки первого взаимодействия
  • INP измеряет все взаимодействия на странице и берёт 98-й перцентиль (самый медленный из 50 взаимодействий)

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

Пороговые значения INP

| Значение | Оценка | |----------|--------| | до 200 мс | Хорошо | | 200 — 500 мс | Требует улучшения | | более 500 мс | Плохо |

Как работает INP

Каждое взаимодействие состоит из трёх фаз:

  1. Input delay — задержка перед началом обработки (главный поток занят)
  2. Processing time — выполнение обработчиков событий
  3. Presentation delay — ожидание рендеринга следующего кадра
INP = max(input delay + processing time + presentation delay)

Браузер вычисляет INP как значение 98-го перцентиля от всех взаимодействий за сессию.

Частые причины плохого INP

  1. Длинные JavaScript задачи — задачи более 50 мс блокируют главный поток
  2. Тяжёлые обработчики событий — onclick/oninput выполняют слишком много работы
  3. Излишний рендеринг — ненужные перерисовки компонентов
  4. Синхронные операции — блокирующие вызовы в обработчиках
  5. Большой DOM — более 1500 узлов замедляет рендеринг

Как улучшить INP

1. Разбивать длинные задачи

// Плохо: одна большая задача блокирует поток
function processData(items) {
  items.forEach(item => heavyCompute(item));
}

// Хорошо: разбиваем с yield
async function processData(items) {
  for (const item of items) {
    heavyCompute(item);
    // Передаём управление браузеру между итерациями
    await scheduler.yield();
  }
}

2. Оптимизировать обработчики событий

// Плохо: вся логика в click обработчике
button.addEventListener('click', () => {
  const data = fetchSyncData();  // синхронный запрос
  renderHeavyUI(data);           // тяжёлый рендеринг
  analytics.track('click');      // аналитика
});

// Хорошо: только критическое, остальное отложено
button.addEventListener('click', () => {
  updateUI();  // только обновление UI

  // Остальное через setTimeout или requestIdleCallback
  setTimeout(() => analytics.track('click'), 0);
  requestIdleCallback(() => syncData());
});

3. Web Workers для тяжёлых вычислений

// Перенести тяжёлую обработку в фоновый поток
const worker = new Worker('/data-processor.js');
worker.postMessage(largeDataset);
worker.onmessage = (e) => updateUI(e.data);

4. Дебаунсинг частых событий

// input/scroll события срабатывают очень часто
const handleInput = debounce((e) => {
  // Обработка только после паузы ввода
  searchAPI(e.target.value);
}, 300);

input.addEventListener('input', handleInput);

5. Виртуализация длинных списков

// Рендерить только видимые элементы
// Используйте react-virtual, @tanstack/virtual
import { useVirtualizer } from '@tanstack/react-virtual';

Измерение INP

import {onINP} from 'web-vitals';
onINP(metric => {
  console.log('INP:', metric.value, 'мс');
  console.log('Худшее взаимодействие:', metric.attribution);
});

В Chrome DevTools → Performance → смотрите Interaction Timeline для анализа конкретных взаимодействий.

Проверка INP на reChecker

Используйте Web Vitals для анализа отзывчивости страницы. Инструмент покажет:

  • Текущее значение INP
  • Оценку отзывчивости (хорошо/требует улучшения/плохо)
  • Все метрики Core Web Vitals

FAQ

INP можно измерить в лаборатории? Частично. Lighthouse и PageSpeed Insights показывают TBT (Total Blocking Time) как лабораторный прокси для INP. Сам INP измеряется только по реальным данным пользователей (CrUX), так как требует реальных взаимодействий.

Почему INP плохой на SPA (React/Vue)? Single Page Applications при навигации выполняют тяжёлый JS: unmount компонентов, fetch данных, mount новых компонентов — всё это блокирует главный поток. Решение: React Concurrent Features, Suspense, код-сплиттинг.

Как найти виновника плохого INP? Chrome DevTools → Performance → запишите сессию с взаимодействием → найдите долгие задачи (длиннее 50 мс) в Timeline. Раздел Interactions покажет какие взаимодействия были медленными.

Попробуйте инструмент

Проверьте inp (interaction to next paint) на вашем сайте с помощью бесплатного инструмента.

Web Vitals

Техническая поддержка

Нашли баг, сбой или ошибку в работе сервиса? Есть предложение по улучшению? Напишите нам — мы читаем каждое сообщение и стараемся быстро исправлять проблемы.