Interaction to Next Paint (INP)

Co je INP (Interaction to Next Paint) a proč je důležitý

INP (Interaction to Next Paint) je metrika rychlosti odezvy rozhraní, která měří, jak rychle stránka vizuálně zareaguje na interakci uživatele. Na rozdíl od historické metriky FID (First Input Delay) sleduje celý průběh interakce až po nejbližší viditelné překreslení (paint) a zohledňuje tak nejen zpoždění při startu, ale také zpracování a vykreslení výsledku. V Core Web Vitals je INP primárním ukazatelem odezvy a kvality interakcí.

Jak se INP počítá: tři fáze interakce

  • Input delay – doba od vstupu (klik, tap, klávesa) po začátek zpracování handleru na hlavním vlákně.
  • Processing time – čas vykonávání obslužného kódu (event handler, logika, aktualizace stavu).
  • Presentation delay – doba potřebná, než prohlížeč aktualizuje DOM/CSSOM, rozložení, malování a výsledek se objeví na obrazovce.

INP je definován jako zástupce „nejhorší typické interakce“ na relaci (např. 98. percentil interakcí), aby byly penalizovány sporadické, ale reálně vnímané špičky latence.

Prahové hodnoty: co je dobré, co je potřeba zlepšit a co je špatné

  • Dobré: ≤ 200 ms (uživatel subjektivně vnímá okamžitou odezvu).
  • Potřebné zlepšení: > 200 ms a ≤ 500 ms (odezva je znatelná, ale tolerovatelná).
  • Špatné: > 500 ms (frustrující odezva, snižuje konverze a angažovanost).

Jaké interakce INP sleduje

  • Ukazovací interakce: klik myší, tap na dotykovém zařízení.
  • Textová interakce: stisk klávesy, potvrzení formuláře.
  • Kompozitní gesta: např. rozbalení menu, přepnutí záložky, otevření modalu.

Scroll a gesta na „samostatném“ vláknu (compositor thread) se obvykle nepočítají, pokud nejsou spojena s event handlerem, který blokuje hlavní vlákno.

Propojení s ostatními Core Web Vitals

  • LCP (Largest Contentful Paint) – vnímané načítání; optimalizace LCP snižuje zátěž hlavního vlákna na začátku relace.
  • CLS (Cumulative Layout Shift) – stabilita rozložení; snižuje presentation delay po interakci.
  • INP – dynamická odezva po načtení; týká se zejména JavaScriptu a renderovacích průchodů.

Typické příčiny špatného INP

  • Dlouhé úlohy (Long Tasks > 50 ms) na hlavním vlákně – bundly, synchronní výpočty, JSON parsování, složité smyčky.
  • Nadměrná pracnost v event handlerech – složitá logika, masivní manipulace s DOM, synchronní I/O (např. localStorage).
  • Reflow/repaint bubliny – časté čtení a zápis do rozložení během jednoho ticku.
  • Hydratace SPA/MPA – opožděné připojení handlerů, blokující inicializace knihoven.
  • Render „na vše“ – zbytečné re-renderování celého stromu komponent při malé změně stavu.

Diagnostika: laboratorní vs. terénní měření

  • Laboratorní (syntetické) – pomocí nástrojů jako Lighthouse nebo WebPageTest. Vhodné pro iterace, ale INP je interakční metrika, proto laboratorní hodnoty mohou být pouze indikativní.
  • Terénní (RUM) – reálná zařízení a sítě. Sbírejte percentily (p50/p75/p95) a segmentujte podle zařízení, OS, prohlížeče a cesty (stránka → typ interakce).

Implementujte knihovnu web-vitals nebo vlastní RUM měření, zaznamenávejte typ interakce, časové značky a identifikátor komponenty.

Měřící plán pro INP: co logovat

  • Časové složky: input delay, processing time, presentation delay, celkový INP.
  • Kontext: typ eventu, název komponenty (např. „AddToCartButton“), zda šlo o první interakci po zobrazení.
  • Technické proměnné: velikost JS na stránce, počet dlouhých úloh, TTFB, device memory, effective connection type.
  • Výsledek: zda došlo k navigaci, otevření modalu, ověření formuláře atd.

Optimalizační strategie: od architektury po komponenty

  1. Omezte práci na hlavním vlákně – rozdělte dlouhé úlohy (scheduler.postTask, requestIdleCallback, chunkování smyček), využívejte Web Workers pro CPU náročné operace.
  2. Lazujte hydrataci – partial/odložitelná hydratace, ostrovní architektura, selektivní připojování handlerů až při viditelnosti nebo signálu záměru.
  3. Minimalizujte JS – code-splitting na úrovni routy i komponenty, tree-shaking, odstraňování polyfillů pro moderní prohlížeče.
  4. Event handlery dělejte krátké – nechť handler pouze zaznamená záměr, spustí mikrotask a rychle vrátí kontrolu; UI aktualizace dávkujte.
  5. Optimalizujte render – memoizace, selektivní re-renderování (signály/store architektury), virtuální list/virtualizace, vyhněte se synchronnímu layout thrashingu.
  6. CSS a layout – používejte containment (content-visibility, contain), předvídatelné velikosti prvků, vyhněte se masivním reflow při interakcích.
  7. Grafika a animace – preferujte kompozitor (transformace/opacity), vyhněte se box-shadow a velkým blur efektům během interakce.

Vzorný design handleru s minimem blokování

Při kliknutí proveďte pouze nezbytné minimum a plánujte další kroky asynchronně:

  • Ihned změňte stav tlačítka (loading/disabled) a přidejte ARIA atributy.
  • Spusťte asynchronní logiku (fetch, výpočty) mimo hlavní vlákno nebo v mikro/makro taskech.
  • Dávkujte DOM změny do jednoho renderu (např. v rámci requestAnimationFrame).

Tím se zkrátí presentation delay a uživatel vidí reakci prakticky okamžitě (i když finální data dorazí později).

Frameworky a INP: doporučení podle typu UI

  • React: používejte concurrent rendering, useTransition pro neurgentní aktualizace, memoizujte selektivně, server components ke snížení JS na klientovi.
  • Vue: defineComponent + script setup, granularita reaktivity (signály), lazy registrace komponent, v-memo a keep-alive pro těžké podstromy.
  • Solid/Qwik/Svelte: využijte jemnozrnnou reaktivitu, resumovanou hydrataci, ostrovní model a streaming SSR.
  • MPA s malým JS: progresivně rozšiřujte interakce; použijte defer, priority hinty, modulární import pouze pro interaktivní ostrovy.

Minimalizace presentation delay: taktiky pro okamžitou vizuální zpětnou vazbu

  • Optimistické UI – okamžitě zobrazte očekávanou změnu (např. přepnutý stav), později případná korekce.
  • Skeletony a placeholdery – vizuální důkaz odezvy, který neblokuje vlákno.
  • Připravené vrstvy – rezervujte místo pro modal/panel dopředu, aby otevření nevyvolalo těžký reflow.
  • Předběžná cacheprefetch/prerender nejbližších akcí (např. detail po kliknutí na kartu).

Prioritizace a plán refaktoringu pro lepší INP

  1. Identifikujte „horké“ interakce – podle frekvence a vlivu na cestu ke konverzi (přidání do košíku, filtrování, vyhledávání, přihlášení).
  2. Namapujte příčiny – trace hlavních dlouhých úloh, kdo je spouští (knihovna, komponenta, polyfill).
  3. Stanovte cíle – p75 INP ≤ 200 ms pro klíčové interakce; p95 ≤ 300–400 ms jako „guardrail“.
  4. Iterujte – rychlé vítězství (debounce/throttle, lazy importy), následně architektonické změny (SSR, ostrovy, workery).

Formuláře a INP: speciální doporučení

  • Validaci rozdělte na lightweight (okamžitá) a heavy (asynchronní po uvolnění hlavního vlákna).
  • Při potvrzení formuláře zobrazte stav do 50 ms (spinner, disabled), síťový request spouštějte asynchronně.
  • Vyhněte se synchronnímu čtení layoutu při každém stisku klávesy.

Komponenty filtrů a seznamů: jak se vyhnout nákladným re-renderům

  • Virtualizujte seznamy, dávkujte změny filtrů (aplikujte na jedno kliknutí).
  • Oddělte stav UI (vizuální) od stavu dat (filtr dotazu) a synchronizujte je během idle.
  • Přepočty filtrů delegujte na web worker, UI mějte okamžité.

Síť a INP: proč rychlá odpověď nestačí

Síťové zpoždění ovlivňuje „hot path“ až po kliknutí (fetch). I když má server rychlou odezvu, špatné zpracování na klientovi (parsování JSON, render) může výrazně prodloužit presentation delay. Proto optimalizujte i formát dat (streaming, partial responses, menší JSON, komprese) a příjem na klientovi (inkrementální zobrazování).

Monitoring a reporting: KPI, alerty, segmenty

  • Hlavní KPI: p75 INP na stránku a na typ interakce.
  • Segmentace: zařízení (mobile/desktop), prohlížeč, země, sítě (4G/5G/Wi-Fi), vstupní cesta.
  • Korelace: počet dlouhých úloh, velikost JS, TTI/TTFB, počet re-renderů.
  • Alerty: náhlé zhoršení p95 INP po releasu (regrese v konkrétním modulu).

Check-list pro zlepšení INP (rychlá vítězství)

  • Rozdělte všechny úlohy > 50–75 ms; zaveďte sledování Long Tasks.
  • Přesuňte náročné výpočty do Web Workerů.
  • Zkontrolujte, že event handlery vrací kontrolu do 50 ms.
  • Dávkujte DOM změny; čtení layoutu oddělte od zápisů.
  • Snižte JS o 20–40 % (code-splitting, odstranění nepoužívaných balíků).
  • Zaveďte optimistické UI a okamžitou vizuální zpětnou vazbu.
  • Partial/odložitelná hydratace a ostrovy pro interaktivní sekce.

Příklad „před/po“: tlačítko přidat do košíku

  • Před: klik → synchronní výpočet ceny + render celého košíku → fetch → reflow. INP cca 600–900 ms.
  • Po: klik → okamžitý toggle stavu + badge + async „enqueue“ výpočtů (worker) → inkrementální update. INP cca 120–200 ms.

Přístupnost (a11y) a vnímaná odezva

  • Aktualizujte ARIA live regiony po interakci, aby čtečky obrazov oznamovaly změny bez zpoždění.
  • Správa fokusu – přesné přesuny fokusu po otevření modalu nebo po potvrzení akce.
  • Kontrastní, přehledné stavy „pressed/selected/loading“ – okamžité vizuální potvrzení.

Anti-regresní proces: jak INP udržet dlouhodobě

  • Každý PR s interakcemi musí projít syntetickým testem (trace) a RUM „canary“ percentily.
  • Guardrails: pokud p95 INP stoupne > X %, release se blokuje.
  • Automatizované rozdělení bundlů, kontrola limitů velikosti a detekce nových dlouhých úloh.

Měření úspěchu: dopad na byznys

  • Korelace zlepšení INP s CTR na klíčových prvcích (menu, filtry, košík).
  • Dopad na konverze a odchod z košíku po zkrácení presentation delay.
  • Snížení zákaznických ticketů souvisejících s „nefunkčním“ UI.

Shrnutí

INP měří reálnou kvalitu odezvy na interakce – od vstupu až po viditelnou změnu. Zlepšení vyžaduje snížení práce na hlavním vlákně, krátké handlery, optimalizovaný render a architekturu zaměřenou na ostrovy, workery a inkrementální aktualizace. Při cílech p75 ≤ 200 ms a důsledném RUM monitoringu se odezva stává předvídatelnou, už