Interaction to Next Paint (INP) je v roce 2026 nejčastěji propadanou metrikou Core Web Vitals. Celých 43 % webů nesplňuje hranici 200 ms – a to se přímo podepisuje na pozicích ve vyhledávání i na tom, jak se uživatelé na webu cítí. V tomto průvodci se podíváme na to, proč vaše INP skóre může být špatné, jak přesně diagnostikovat příčiny a hlavně – jak je opravit pomocí konkrétních technik a ukázek kódu.
Co je Interaction to Next Paint a proč na něm záleží
INP nahradilo v březnu 2024 starší metriku First Input Delay (FID) jako oficiální Core Web Vital pro měření interaktivity. Zatímco FID měřilo pouze zpoždění před zpracováním první interakce, INP hodnotí všechny interakce uživatele během celé návštěvy stránky – kliknutí, stisk klávesy, dotyky – a jako výsledné skóre vybírá jednu z nejpomalejších interakcí.
Metrika INP se měří na 75. percentilu. Jinými slovy: 75 % vašich reálných návštěvníků musí mít odezvu interakcí pod 200 ms, aby byl web hodnocen jako „dobrý". A to je přísnější podmínka, než si většina lidí myslí.
Prahové hodnoty INP
- ≤ 200 ms – dobrá odezva
- 200–500 ms – potřebuje zlepšení
- > 500 ms – špatná odezva
Tři fáze interakce: kde vzniká zpoždění
Každá interakce se skládá ze tří fází a problémy v kterékoli z nich zhoršují INP:
- Input Delay (vstupní zpoždění) – doba, po kterou prohlížeč čeká, než může spustit obslužnou funkci, protože hlavní vlákno je zaneprázdněno jiným JavaScriptem.
- Processing Time (doba zpracování) – čas strávený vykonáváním obslužných funkcí (event handlerů) v JavaScriptu.
- Presentation Delay (zpoždění vykreslení) – čas potřebný pro přepočet layoutu, stylů a vykreslení nového snímku na obrazovku.
Pochopení těchto tří fází je klíčové. Bez toho střílíte naslepo – opravujete věci, které třeba vůbec nejsou problémem. Chrome DevTools vám ukáže přesně, ve které fázi se zpoždění hromadí.
Nejčastější příčiny špatného INP
1. Dlouhé JavaScriptové úlohy blokující hlavní vlákno
Jakákoli JavaScriptová úloha, která běží déle než 50 ms, blokuje hlavní vlákno a brání prohlížeči reagovat na vstupy uživatele. JavaScript využívá model „run-to-completion" – každá úloha běží až do konce bez ohledu na to, jak dlouho blokuje vlákno. Tohle je zdroj naprosté většiny INP problémů, na které jsem narazil.
2. Těžké obslužné funkce událostí
Event handlery, které provádějí náročné výpočty, rozsáhlé manipulace s DOM nebo synchronní operace, přímo prodlužují dobu zpracování. Každá milisekunda v obslužné funkci se připočítává k INP.
3. Příliš velký DOM
Stránky s tisíci elementů trvají déle na zpracování interakcí. Střídavé čtení a zápis DOM vlastností navíc nutí prohlížeč opakovaně přepočítávat layout (forced reflow), což dále blokuje hlavní vlákno. Doporučuje se udržovat DOM pod 1 500 uzly – a v praxi tohle číslo e-shopy s velkými katalogy překračují překvapivě snadno.
4. Skripty třetích stran
Reklamní sítě, analytika, chatovací widgety a sociální pluginy soupeří o čas na hlavním vlákně. Často jsou to právě tyto skripty, které způsobují vstupní zpoždění při interakcích – a jejich autoři o optimalizaci INP příliš nepřemýšlí.
5. Hydratace frameworku
U aplikací postavených na Reactu, Vue nebo Angular může hydratace celé stránky způsobit dlouhé blokování hlavního vlákna, během něhož jsou interakce výrazně zpožděné.
Jak diagnostikovat INP problémy
Chrome DevTools – Performance panel
Otevřete DevTools (F12), přejděte na záložku Performance a zaznamenejte interakci s vaší stránkou. V tracku Interactions uvidíte varování u interakcí delších než 200 ms – jsou označeny červeným trojúhelníkem.
Po kliknutí na interakci se zobrazí rozpad INP na tři složky: Input Delay, Processing Time a Presentation Delay. Vysoký Input Delay ukazuje na aktivitu na pozadí, vysoký Processing Time na pomalé event handlery a vysoký Presentation Delay na náročné přepočty layoutu a vykreslování.
Tip: Zapněte CPU throttling (4x nebo 6x) v nastavení Performance panelu, abyste emulovali slabší zařízení. Mnozí vaši uživatelé nemají výkonné počítače – a to, co vám na MacBooku připadá svižné, může být na středním Androidu tragédie.
Long Animation Frames API (LoAF)
API Long Animation Frames (LoAF), dostupné od Chrome 123, poskytuje podrobnější informace než starší Long Tasks API. Zatímco Long Tasks API měří jen jednotlivé úlohy, LoAF sleduje celé animační snímky včetně requestAnimationFrame callbacků, resize observerů a dalších fází vykreslování.
Snímek je považován za „dlouhý", pokud trvá déle než 50 ms. Knihovna web-vitals od verze 4 automaticky propojuje INP záznamy s příslušnými LoAF, takže přesně vidíte, které skripty způsobily zpomalení.
// Sledování Long Animation Frames
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log('LoAF trvání:', entry.duration, 'ms');
// Zobrazení skriptů, které běžely v rámci snímku
for (const script of entry.scripts) {
console.log('Skript:', script.sourceURL);
console.log('Doba běhu:', script.duration, 'ms');
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
Strategie opravy INP: krok za krokem s ukázkami kódu
Strategie 1: Rozdělte dlouhé úlohy pomocí scheduler.yield()
API scheduler.yield() je v roce 2026 nejelegantnější způsob, jak rozdělit dlouhé úlohy. Na rozdíl od setTimeout, který řadí pokračování na konec fronty, scheduler.yield() ho řadí na začátek – takže vaše práce nebude přerušena skripty třetích stran. Tohle je detail, který dělá velký rozdíl.
// Funkce pro bezpečné yielding s fallbackem
async function yieldToMain() {
if ('scheduler' in window && 'yield' in scheduler) {
return scheduler.yield();
}
// Fallback pro prohlížeče bez podpory
return new Promise((resolve) => setTimeout(resolve, 0));
}
// Použití při zpracování velkého seznamu
async function processItems(items) {
for (let i = 0; i < items.length; i++) {
processItem(items[i]);
// Každých 10 položek uvolníme hlavní vlákno
if (i % 10 === 0) {
await yieldToMain();
}
}
}
scheduler.yield() je podporováno od Chrome 115. Pro ostatní prohlížeče používejte fallback na setTimeout nebo polyfill scheduler-polyfill.
Strategie 2: Okamžitá vizuální zpětná vazba, odložené zpracování
Klíčový vzor pro rychlé INP: okamžitě aktualizujte vizuální stav (CSS třída, spinner) a teprve poté spusťte náročnou operaci. Díky requestAnimationFrame a setTimeout prohlížeč stihne vykreslit změnu před spuštěním těžkého kódu.
// Špatně: všechno blokuje hlavní vlákno
searchInput.addEventListener('input', () => {
searchButton.classList.add('loading');
renderSearchResults(); // pomalá funkce – blokuje snímek
});
// Správně: vizuální zpětná vazba je okamžitá
searchInput.addEventListener('input', () => {
requestAnimationFrame(() => {
searchButton.classList.add('loading'); // prohlížeč vykreslí ihned
setTimeout(() => {
renderSearchResults(); // běží až po vykreslení
}, 0);
});
});
Strategie 3: Zpracování dat po částech (chunking)
Pokud potřebujete zpracovat velký objem dat (třeba filtrovat tisíce položek), rozdělte práci do menších bloků. Tím zajistíte, že hlavní vlákno zůstane volné pro reakci na interakce uživatele.
// Špatně: zpracování celého seznamu najednou
function filterProducts(products, query) {
return products.filter(p =>
p.name.toLowerCase().includes(query.toLowerCase())
);
}
// Správně: zpracování po blocích s uvolněním vlákna
async function filterProductsChunked(products, query, chunkSize = 100) {
const results = [];
const lowerQuery = query.toLowerCase();
for (let i = 0; i < products.length; i += chunkSize) {
const chunk = products.slice(i, i + chunkSize);
const filtered = chunk.filter(p =>
p.name.toLowerCase().includes(lowerQuery)
);
results.push(...filtered);
// Uvolnění vlákna mezi bloky
await yieldToMain();
}
return results;
}
Strategie 4: Přesuňte těžké výpočty do Web Workerů
Web Workers běží ve vlastním vlákně, mimo hlavní vlákno prohlížeče. Jsou ideální pro výpočetně náročné operace, které by jinak blokovaly interakce – například zpracování dat, řazení velkých polí nebo komprese. Poprvé jsem tohle řešení nasadil na e-shop s katalogem přes 50 000 produktů a výsledek předčil očekávání.
// heavy-worker.js – kód běžící v samostatném vlákně
self.onmessage = function(e) {
const { data, sortKey } = e.data;
// Náročné řazení mimo hlavní vlákno
const sorted = data.sort((a, b) =>
a[sortKey].localeCompare(b[sortKey])
);
self.postMessage(sorted);
};
// Hlavní skript – delegace práce na worker
const worker = new Worker('heavy-worker.js');
sortButton.addEventListener('click', () => {
sortButton.classList.add('loading');
worker.postMessage({ data: largeDataset, sortKey: 'name' });
});
worker.onmessage = (e) => {
renderTable(e.data);
sortButton.classList.remove('loading');
};
Strategie 5: Dynamické importy a lazy loading
Nenačítejte veškerý JavaScript předem. Pomocí dynamických importů (import()) načtěte kód až ve chvíli, kdy ho uživatel skutečně potřebuje. To sníží objem JavaScriptu na hlavním vlákně při počátečním načtení a zmenší vstupní zpoždění.
// Špatně: import celé knihovny při načtení stránky
import { Chart } from 'chart.js';
// Správně: načtení až při interakci uživatele
chartButton.addEventListener('click', async () => {
chartButton.classList.add('loading');
const { Chart } = await import('chart.js');
const chart = new Chart(canvas, config);
chartButton.classList.remove('loading');
});
Strategie 6: CSS content-visibility pro redukci vykreslování
Vlastnost content-visibility: auto říká prohlížeči, aby přeskočil vykreslování obsahu, který není ve viditelné oblasti. To snižuje práci při vykreslování a zlepšuje Presentation Delay složku INP – přičemž změna v CSS je doslova jednořádková.
/* Líné vykreslování sekcí mimo viewport */
.offscreen-section {
content-visibility: auto;
contain-intrinsic-size: 0 600px;
}
Strategie 7: Správa skriptů třetích stran
Skripty třetích stran jsou jednou z nejčastějších příčin špatného INP. Audit provedete pomocí Lighthouse auditu „Reduce the impact of third-party code". Praktické kroky:
- Odložte nekritické skripty – analytiku a chatovací widgety načítejte s atributem
defernebo až po interakci. - Facade pattern – nahraďte těžké widgety (YouTube embed, sociální tlačítka) statickým náhledem, který se načte až po kliknutí.
- Zvažte alternativy na edge – nástroje jako Cloudflare Zaraz přesunou analytiku a třetí strany na edge server, takže vůbec neblokují hlavní vlákno v prohlížeči.
<!-- Facade pattern pro YouTube embed -->
<div class="youtube-facade"
data-video-id="dQw4w9WgXcQ"
onclick="loadYouTubeEmbed(this)">
<img src="/img/youtube-thumbnail.webp"
alt="Video náhled" loading="lazy" />
<button aria-label="Přehrát video">▶</button>
</div>
<script>
function loadYouTubeEmbed(el) {
const id = el.dataset.videoId;
el.innerHTML = '<iframe src="https://www.youtube.com/embed/'
+ id + '?autoplay=1" allowfullscreen></iframe>';
}
</script>
Pokročilé přístupy: islands architektura a partial hydration
Moderní frameworky jako Astro a Qwik v roce 2026 nabízejí architekturu „ostrovů" (islands), kde se hydratuje pouze interaktivní část stránky. Statický obsah zůstává čistým HTML bez JavaScriptu, což dramaticky snižuje objem kódu na hlavním vlákně a zlepšuje INP i LCP.
Stavíte-li nový projekt nebo zvažujete redesign, tyto přístupy nabízejí nejlepší výsledky INP hned od začátku – jednoduše proto, že minimalizují množství JavaScriptu, které vůbec posíláte do prohlížeče.
Měření výsledků: jak ověřit, že opravy fungují
- PageSpeed Insights – zobrazí field data (CrUX) i laboratorní výsledky. Sledujte 75. percentil INP v sekci Core Web Vitals.
- Google Search Console – v reportu Core Web Vitals uvidíte, kolik stránek má INP problémy a jak se situace vyvíjí v čase.
- Chrome DevTools – záložka Performance pro laboratorní diagnostiku s CPU throttlingem.
- RUM (Real User Monitoring) – nástroje jako DebugBear, SpeedCurve nebo knihovna
web-vitalspro sledování reálných dat od uživatelů.
Zlepšení v laboratorních datech se projeví okamžitě. Zlepšení ve field datech (CrUX) přijde obvykle za 4–8 týdnů, protože Google sbírá data za 28denní klouzavé období – takže trpělivost je tady skutečně nutná.
Checklist optimalizace INP
- Změřte aktuální INP ve field datech (PageSpeed Insights, Search Console).
- Identifikujte nejpomalejší interakce pomocí Chrome DevTools Performance panelu.
- Analyzujte rozpad na tři fáze – zjistěte, zda je problém ve vstupním zpoždění, zpracování nebo vykreslení.
- Pomocí LoAF API určete konkrétní skripty, které blokují hlavní vlákno.
- Aplikujte příslušnou strategii: yield, chunking, Web Workers, lazy loading nebo facade pattern.
- Ověřte zlepšení v laboratorních testech s CPU throttlingem.
- Sledujte field data po dobu 4–8 týdnů pro potvrzení zlepšení v CrUX.
Často kladené otázky
Jaký je rozdíl mezi INP a FID?
FID měřilo pouze zpoždění před zpracováním první interakce uživatele. INP hodnotí všechny interakce během celé návštěvy a zahrnuje kompletní životní cyklus interakce – od vstupu přes zpracování až po vykreslení. INP je proto mnohem přísnější a přesnější metrika, která lépe odráží skutečný uživatelský zážitek.
Jak rychle se projeví zlepšení INP v pozicích na Googlu?
Laboratorní data (Lighthouse, PageSpeed Insights) se aktualizují okamžitě. Field data v Chrome UX Report (CrUX) se aktualizují za 28denní klouzavé období, takže reálné zlepšení v Google Search Console uvidíte typicky za 4–8 týdnů po nasazení oprav.
Je scheduler.yield() podporován ve všech prohlížečích?
Ne. V roce 2026 je scheduler.yield() podporován v Chromium prohlížečích od verze 115 (Chrome, Edge, Opera). Pro Firefox a Safari je nutné používat polyfill (scheduler-polyfill) nebo fallback na setTimeout. Vždy implementujte detekci funkcí s fallbackem – tohle fakt nevynechávejte.
Může špatné INP skóre ovlivnit pozice mého webu ve vyhledávání?
Ano. INP je jednou ze tří metrik Core Web Vitals, které Google používá jako signál pro hodnocení stránek. Weby s dobrými Core Web Vitals mají v průměru o 24 % nižší bounce rate a lepší organické pozice. Vliv není dramatický jako u relevance obsahu, ale při ostatních srovnatelných faktorech může rozhodovat.
Jak velký DOM je příliš velký pro dobré INP?
Google doporučuje udržovat DOM pod 1 500 uzly, s maximální hloubkou 32 úrovní a žádným rodičovským uzlem s více než 60 dětmi. Větší DOM znamená delší přepočty layoutu a stylů, což se přímo projevuje ve fázi Presentation Delay metriky INP.