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 дні. Замовте консультацію — розберемо ваш випадок безкоштовно.







