Spis treści +
„Nigdy nie blokuj main thread” to dobra domyślna zasada. Jak wszystkie domyślne zasady, bywa łamana świadomie, albo przez przypadek z jQuery z 2014.
Co to w ogóle znaczy
Główny wątek przeglądarki maluje piksele, obsługuje kliknięcia, parsuje HTML. Gdy JS liczy coś ciężkiego synchronicznie, strona „zamraża się”: scroll nie idzie, przycisk nie reaguje, INP leci w kosmos.
Lighthouse / Performance panel pokazuje long taski (powyżej 50 ms). Na mobile ten sam kod boli mocniej niż na Twoim Maku.
Kiedy to zwykle błąd
- Ogromny bundle na starcie (cały GSAP + trzy carousele + chat widget) zanim user cokolwiek zobaczy.
- Synchroniczne
JSON.parsewielkiego feedu przyDOMContentLoaded. - Polyfille ładowane wszystkim, także przeglądarkom, które ich nie potrzebują.
- Animacje na właściwościach layoutu w pętli.
Objaw: „strona się załadowała, ale jest jakaś taka ociężała”.
Kiedy kompromis bywa OK
Rzadko, i warto to nazwać w code review:
- Krytyczna operacja płatności / checksum, która musi skończyć się zanim user kliknie dalej, i trwa poniżej 100 ms.
- Jednorazowa inicjalizacja małej biblioteki w momencie, gdy user właśnie otworzył overlay (nie przy starcie strony).
- Świadomy trade-off na desktop-only tool (panel wewnętrzny), gdzie INP nie jest KPI.
Nawet wtedy: requestIdleCallback, scheduler, Web Worker albo przynajmniej rozbicie na chunki z setTimeout(0) bywa tańsze niż „zablokuj na 400 ms i trudno”.
Co mówić developerowi na spotkaniu
- „Czy ten skrypt musi być na pierwszym ekranie?”
- „Da się go załadować przy
client:visible/ intersection?” - „Jaki jest long task na mid-tier Androidzie, nie na Twoim laptopie?”
Jeśli odpowiedź brzmi „biblioteka tak ma”, szukajcie lżejszej biblioteki albo CSS.
Budujemy fronty pod INP od startu: Astro, mało JS, hydracja tam gdzie trzeba. Jak audytujesz istniejącą: audyt.