INP (Interaction to Next Paint), Core Web Vital 2026:przyczyny, pomiar, poprawki w React/Next.js

INP5 min czytania25 lipca 2026

Autor: DevStudio.it

TL;DR

INP (Interaction to Next Paint) mierzy opóźnienie od interakcji użytkownika (klik, tap, klawisz) do następnego malowania UI, nie tylko „czas do pierwszego handlera”. Od 2024 INP zastąpiło FID w Core Web Vitals; w 2026 Google nadal ocenia strony po progu dobry ≤ 200 ms, wymaga poprawy 200–500 ms, słaby > 500 ms (75. percentyl). Typowe zabójce w React/Next.js: ciężki JS na main thread, synchroniczne setState kaskady, duże listy bez wirtualizacji, third-party na kliknięciu, wolne Server Actions bez optimistic UI. Mierz CrUX + RUM; poprawiaj profilowaniem Performance. Aplikacja na DevStudioIT Cloud, telemetria eventów w Postgres (Branchly). To nie jest ogólny przewodnik LCP/CLS, skupiamy się wyłącznie na INP.

Dla kogo to jest

  • Zespołów Next.js z żółtym/czerwonym INP w Search Console / PageSpeed
  • Frontendowców React po migracji App Router / RSC
  • Produktów z bogatymi formularzami, filtrami, menu mobile
  • Tech leadów ustalających budget „po kliknięciu” na money pages

Fraza (SEO)

INP Interaction to Next Paint 2026, Core Web Vital INP React, poprawa INP Next.js, wolny klik main thread, web-vitals INP pomiar, optymalizacja interakcji React

Co dokładnie mierzy INP

INP bierze pod uwagę całą interakcję:

  1. Input delay, czekanie aż main thread będzie wolny
  2. Processing duration, Twój event handler + React commit
  3. Presentation delay, stylowanie + paint do następnej klatki

Raportowana wartość to zwykle najgorsza (lub wysoki percentyl) interakcja w sesji, nie średnia wszystkich kliknięć. Dlatego jeden wolny „Wyślij formularz” psuje INP nawet jeśli menu jest szybkie.

Ocena (p75) INP
Good ≤ 200 ms
Needs improvement 200–500 ms
Poor > 500 ms

Gdzie w React/Next.js INP najczęściej umiera

1. Za dużo pracy synchronicznej w handlerze

// Źle: ciężkie filtrowanie + setState w tym samym ticku co klik
function onFilter(value: string) {
  const next = hugeCatalog.filter(/* CPU-heavy */);
  setItems(next);
  setFacetCounts(computeFacets(next));
  analytics.track('filter', { value }); // sync XHR?
}

Lepsze: startTransition dla niepilnych update’ów, odłóż analytics na requestIdleCallback / kolejkę, dziel pracę (scheduler).

2. Re-rendery całego drzewa

Klik w toggle w headerze przerenderowuje 200 kart produktów. Rozwiązania: izolacja stanu (bliżej liścia), kompozycja children, unikaj Contextów „na wszystko”, w RSC trzymaj interaktywność w małych Client Components.

3. Hydration i „klik zanim ready”

Użytkownik klika zanim hydracja skończy, kolejka eventów + ciężki hydrate = zły INP. Preferuj Server Components, mniejszy client bundle, loading.tsx / selective hydration.

4. Third-party na ścieżce interakcji

Chat widget, heatmap, A/B SDK ładujące się w handlerze CTA. Ładuj defer / po idle; nie blokuj first interaction na money page.

5. Formularze i Server Actions bez feedbacku

Długi round-trip bez optimistic UI sprawia wrażenie „zamarcia”; INP obejmuje czas do paint wskaźnika ładowania. Natychmiast pokaż pending state (useFormStatus / useTransition).

Pomiar: lab vs field

Źródło Co daje Limit
Chrome DevTools Performance dokładny call stack nie jest p75 użytkowników
Lighthouse / PSI lab estimate inne urządzenie niż CrUX
CrUX / Search Console real users p75 wolna aktualizacja
web-vitals RUM per URL / device musisz zbierać sam
import { onINP } from 'web-vitals';

onINP((metric) => {
  // wyślij do swojego endpointu → Branchly
  navigator.sendBeacon('/api/rum', JSON.stringify({
    name: metric.name,
    value: metric.value,
    id: metric.id,
    pathname: location.pathname,
  }));
});

Zapis RUM w Branchly pozwala korelować INP z konkretnym CTA (formularz vs menu), nie tylko „cała domena czerwona”.

Profilowanie: jak znaleźć winnego

  1. DevTools → Performance → nagraj klik problematyczny
  2. Szukaj długich Tasks (czerwone) między input a paint
  3. Rozwiń call stack: React commit, Twój handler, third-party
  4. React Profiler: które komponenty commit’ują przy tym kliknięciu
  5. Coverage / bundle: czy handler importuje ciężki moduł (lodash full, moment, chart)?

Na stagingu DevStudioIT Cloud testuj na throttled CPU 4–6×, desktop „instant” ukrywa mobile INP.

Konkretne poprawki (checklista kodu)

Problem Fix
Ciężki setState na klik startTransition / useDeferredValue
Duża lista wirtualizacja (@tanstack/react-virtual)
Globalny context split context lub props drilling lokalnie
Sync analytics beacon / idle queue
Duży client component split + dynamic ssr: false tylko gdy konieczne
CSS thrash unikaj layout read/write na przemian w handlerze
Obrazy w menu priority tylko LCP; reszta lazy
Debounce input dla search-as-you-type; dla przycisku nie delay’uj paint
'use client';
import { useTransition, useState } from 'react';

export function FacetButton({ id, label }: { id: string; label: string }) {
  const [active, setActive] = useState(false);
  const [isPending, startTransition] = useTransition();

  return (
    <button
      data-pending={isPending}
      onClick={() => {
        setActive((v) => !v); // pilny feedback UI
        startTransition(() => {
          applyFacet(id); // ciężkie filtrowanie listy
        });
      }}
    >
      {label}
    </button>
  );
}

Natychmiastowy paint atrybutu / klasy = lepsze INP; ciężka praca w transition.

INP a SEO, co realnie się dzieje

Google używa field data (CrUX) dla CWV w rankingach jako jeden z wielu sygnałów. Słabe INP na kluczowych URL (homepage, oferta, kontakt) może pogarszać UX i pośrednio konwersję niezależnie od pozycji. Naprawiaj URL z ruchem i leadami, nie każdą podstronę bloga z 12 sesjami/miesiąc.

FAQ

Czy INP dotyczy tylko mobile?

Raporty CrUX rozdzielają mobile/desktop. Mobile zwykle gorsze, priorytet napraw. Desktop też bywa słaby przy ciężkich dashboardach.

Czy loading.tsx poprawia INP?

Pomaga UX nawigacji (Suspense), ale nie zastępuje optymalizacji handlerów na tej samej stronie. INP = interakcje, nie tylko route transitions.

Czy React Compiler / memo wszystko naprawi?

Zmniejsza zbędne re-rendery, ale nie usuwa 200 ms synchronicznego JSON.parse w onClick. Najpierw skróć pracę w handlerze.

FID vs INP, muszę jeszcze patrzeć na FID?

Dla CWV 2026 fokus to INP. FID jest historyczne; narzędzia mogą jeszcze pokazywać FID, nie optymalizuj tylko pod FID.

Chcesz obniżyć INP na produkcji?

Powiązane wpisy

Sygnały zaufania na stronie firmowej, konwersja i E-E-A-T w 2026
6 min czytania
Schema FAQPage i rich results, kiedy Google pokazuje FAQ (2026)
5 min czytania
robots.txt w Next.js App Router, crawl budget i pułapki Disallow (2026)
5 min czytania

O autorze

Budujemy szybkie strony WWW, aplikacje web/mobile, chatboty AI i hosting — z naciskiem na SEO i konwersję.

Przydatne linki

Od teorii do produkcji — Branchly, hosting i realizacje.

Podoba Ci się nasze podejście? Zbudujmy coś razem.

Rozpocznij konfigurację projektu