Ciężka obsługa zdarzenia: dlaczego kliknięcie trwa 500 ms i jak to naprawić
Co się dzieje
Gdy użytkownik klika, przeglądarka wykonuje obsługę zdarzenia do końca, zanim może narysować kolejną klatkę. Jeśli obsługa wykonuje setki milisekund synchronicznej pracy — filtrowanie dużej tablicy, budowanie DOM, parsowanie JSON — strona jest zamrożona dokładnie na ten czas. Użytkownik nie widzi nic, dopóki obsługa nie zwróci sterowania.
To najczęstszy problem z INP; w rozbiciu INP widać go jako długą fazę processing time.
Jak rozpoznać
- Processing time dominuje w rozbiciu INP (input delay i presentation delay są małe).
- W DevTools Performance jedno długie zadanie zaczyna się dokładnie na zdarzeniu i jest przypisane do Twojej funkcji obsługi.
- Spowolnienie rośnie z rozmiarem danych: im więcej wierszy/elementów, tym gorsze wrażenie z kliknięcia.
Jak naprawić
- Najpierw zaktualizuj UI (stan wciśnięcia, spinner), a następnie oddaj sterowanie przeglądarce przez scheduler.yield() (lub setTimeout(0) jako rozwiązanie awaryjne) przed wykonaniem ciężkiej pracy.
- Podziel duże pętle na części, oddając sterowanie między nimi, aby przeglądarka mogła narysować klatkę.
- Przenieś czyste obliczenia (parsowanie, filtrowanie, diffowanie) do Web Workera — główny wątek tylko wysyła dane i odbiera wynik.
Problem
button.addEventListener("click", () => {
const results = filterRows(allRows) // 400 ms of sync work
renderTable(results) // user saw nothing until now
})
Poprawka
button.addEventListener("click", async () => {
button.classList.add("loading") // instant feedback, painted first
await scheduler.yield() // let the browser paint
const results = filterRows(allRows)
renderTable(results)
button.classList.remove("loading")
})
Przeskanuj swoją stronę za darmo →