INP стал критической метрикой Core Web Vitals — с марта 2024 он заменяет FID и учитывает все взаимодействия пользователя. Плохой INP (более 200 мс) напрямую снижает конверсию: каждая 100 мс задержки при вводе в поиск или клике на кнопку уводит 1–2% посетителей. Мы помогаем клиентам достичь значения ≤200 мс и подтверждаем результат инструментальным мониторингом за счёт комбинации разбивки Long Tasks, асинхронной фильтрации и выноса тяжёлых вычислений в Web Workers.
Как работает INP
INP = время от действия пользователя (mousedown, keydown, pointerdown) до следующей отрисовки фрейма браузером. Задержка складывается из трёх фаз: input delay — ожидание, пока main thread освободится; processing time — выполнение обработчиков событий; presentation delay — layout, paint, composite. Типичная ситуация: пользователь кликает кнопку фильтрации, но main thread занят парсингом аналитического скрипта — клик ждёт 120 мс, затем обработчик выполняется 80 мс, ещё 50 мс на отрисовку — итого 250 мс, что уже за пределами нормы.
Почему INP критичен для SEO?
Google сделал INP одним из трёх ключевых сигналов ранжирования. Сайты с INP > 200 мс теряют позиции в выдаче и получают меньше органического трафика. Для интернет-магазинов каждая миллисекунда задержки снижает конверсию на 1–2%. В одном из проектов после снижения INP с 350 мс до 80 мс конверсия выросла на 12%, а средняя глубина просмотра увеличилась на 2 страницы.
Диагностика медленных взаимодействий
Используйте PerformanceObserver для сбора всех взаимодействий с задержкой >16 мс:
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.duration > 200) {
console.warn(`Slow interaction: ${entry.name}`, {
duration: entry.duration,
processingStart: entry.processingStart,
processingEnd: entry.processingEnd,
inputDelay: entry.processingStart - entry.startTime,
processingTime: entry.processingEnd - entry.processingStart,
presentationDelay: entry.startTime + entry.duration - entry.processingEnd,
});
}
}
}).observe({ type: 'event', buffered: true, durationThreshold: 16 });
Chrome DevTools → Performance → запись страницы → фильтр Long Tasks. Любая задача > 50 мс — кандидат на оптимизацию. В реальной сессии мы часто видим Long Tasks от 100 до 500 мс, создаваемые сторонними скриптами или тяжёлыми вычислениями на основном потоке.
Устранение Long Tasks: два подхода
Разбивка через yield подходит для лёгких вычислений. Web Worker лучше для CPU-интенсивных задач, так как полностью освобождает main thread. Пример из практики: в интернет-магазине фильтрация по 20 000 товаров в реальном времени давала INP 350 мс. Мы вынесли фильтрацию в Web Worker и добавили виртуализацию списка — INP упал до 80 мс.
// Async filter с yield каждые 50 элементов
async function filterProductsAsync(products, filters) {
const results = [];
for (let i = 0; i < products.length; i++) {
if (matchesFilters(products[i], filters)) {
results.push(products[i]);
}
if (i % 50 === 0 && i > 0) {
await scheduler.yield(); // Chrome 115+
// fallback: await new Promise(r => setTimeout(r, 0));
}
}
return results;
}
// Web Worker – вынос тяжёлой фильтрации
// worker.js
self.onmessage = function({ data: { products, filters } }) {
const results = products.filter(p => matchesFilters(p, filters));
self.postMessage(results);
};
// main.js
const worker = new Worker('/js/filter-worker.js');
worker.postMessage({ products, filters });
worker.onmessage = ({ data }) => setFilteredProducts(data);
Оптимизация React-компонентов
Проблема: синхронная фильтрация на каждый keystroke блокирует main thread. Решение — useTransition и виртуализация. Вот как выглядит компонент поиска с мгновенным откликом:
function ProductList() {
const [query, setQuery] = useState('');
const [deferredQuery, setDeferredQuery] = useState('');
const filtered = useMemo(
() => products.filter(p => p.name.toLowerCase().includes(deferredQuery.toLowerCase())),
[deferredQuery]
);
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
const value = e.target.value;
setQuery(value); // срочно — поле отзывается мгновенно
startTransition(() => {
setDeferredQuery(value); // некритично — список обновится позже
});
}
return (
<>
<input value={query} onChange={handleChange} />
<ul>
{filtered.map(p => <ProductItem key={p.id} product={p} />)}
</ul>
</>
);
}
Для длинных списков используйте виртуализацию:
import { useVirtualizer } from '@tanstack/react-virtual';
function VirtualProductList({ products }: { products: Product[] }) {
const parentRef = useRef<HTMLDivElement>(null);
const rowVirtualizer = useVirtualizer({
count: products.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 80,
overscan: 5,
});
return (
<div ref={parentRef} style={{ height: '600px', overflow: 'auto' }}>
<div style={{ height: rowVirtualizer.getTotalSize() }}>
{rowVirtualizer.getVirtualItems().map(virtualRow => (
<div key={virtualRow.index}
style={{ transform: `translateY(${virtualRow.start}px)`, position: 'absolute', width: '100%' }}>
<ProductItem product={products[virtualRow.index]} />
</div>
))}
</div>
</div>
);
}
Third-party скрипты: скрытая угроза
Чаты, пиксели, аналитика — частая причина плохого INP. Они выполняются в main thread и блокируют взаимодействия. Решения:
- Загрузка после основного контента (setTimeout 3s после load).
- Использование Partytown для запуска скриптов в Web Worker.
Типичные ошибки при оптимизации INP
- Оптимизация только одного взаимодействия, тогда как INP берёт наихудшее.
- Игнорирование presentation delay — иногда paint занимает больше времени, чем обработчик.
- Использование
setTimeout(0)вместоscheduler.yield()— первый не освобождает поток гарантированно. - Забывают про мобильные устройства: на слабых процессорах Long Tasks возникают чаще.
Как измерить INP в реальном времени?
Настройте Real User Monitoring (RUM) с отправкой метрик в аналитику. Используйте navigator.webdriver для фильтрации ботов. Пример: собирайте все взаимодействия с INP > 200 мс в performanceEntries и отправляйте на бэкенд для анализа. Это позволит выявить проблемные страницы и устройства.
Целевые показатели INP
| Тип взаимодействия | Цель |
|---|---|
| Клик по кнопке | < 100 мс |
| Ввод в поле поиска | < 150 мс |
| Открытие модального окна | < 200 мс |
| Фильтрация каталога | < 200 мс |
Процесс оптимизации INP
- Диагностика — сбор реальных метрик через RUM и лабораторные тесты.
- Анализ — определение топ-5 проблемных взаимодействий с точными значениями задержек.
- Реализация — применение техник (yield, Workers, lazy loading, виртуализация).
- Тестирование — A/B-эксперименты, проверка влияния на конверсию и SEO-трафик.
- Мониторинг — настройка постоянного контроля INP с алертами при превышении 200 мс.
Сроки ориентировочно
От 3 до 7 дней — в зависимости от числа проблемных взаимодействий и сложности архитектуры. Стоимость рассчитывается индивидуально после аудита.
Более 50 успешных оптимизаций INP. Гарантируем достижение ≤200 мс или возвращаем деньги. Свяжитесь с нами для аудита и получите план оптимизации за 3 дня. Закажите консультацию — разберём ваш случай бесплатно.







