Dlaczego debounce i throttle są ważne w interfejsach
Zrozumieć koszt wydajnościowy nieograniczonych obsługiwaczy klawiszy, przewijania i zmiany rozmiaru oraz wiedzieć, kiedy stosować każde rozwiązanie
Dlaczego debounce i throttle są ważne w interfejsach to bezpłatna lekcja React Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej React Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs React Academy zawiera 4 lekcji w sumie.
Zdarzenia użytkownika o wysokiej częstotliwości
Niektóre zdarzenia DOM są wywoływane z niezwykle dużą częstotliwością. Zdarzenie keypress jest wywoływane przy każdym naciśnięciu klawisza. Zdarzenie scroll jest wywoływane dziesiątki razy na sekundę podczas przewijania. Zdarzenie resize jest wywoływane bez przerwy, gdy użytkownik przeciąga krawędź okna. Przetwarzanie każdego zdarzenia osobno może przeciążyć zarówno przeglądarkę, jak i serwer.
Koszt handlerów bez ograniczeń
Jeśli handler keypress wykonuje wywołanie API przy każdym naciśnięciu klawisza, użytkownik wpisujący „React hooks” (11 znaków) powoduje wysłanie 11 żądań sieciowych, z których większość dotyczy niepełnych zapytań. Podobnie aktualizowanie animacji paralaksy przy każdym pikselu przewinięcia powoduje setki ponownych renderowań w React na sekundę. To marnuje zasoby procesora, sieć i baterię.
Działanie debounce
Debounce opóźnia wykonanie do chwili, gdy zdarzenie przestanie być wywoływane przez określony czas. Jeśli użytkownik nadal pisze, timer jest resetowany przy każdym naciśnięciu klawisza. Dopiero po N milisekundach ciszy handler zostaje ostatecznie wykonany jeden raz. Debounce odpowiada na pytanie: „uruchomić to, gdy użytkownik skończy daną czynność”.
Działanie throttle
Throttle ogranicza wykonywanie do najwyżej jednego razu w danym przedziale czasu, niezależnie od liczby wywołanych zdarzeń. Jeśli użytkownik szybko przewija stronę, throttle ustawiony na 100 ms gwarantuje, że handler zostanie wykonany nie częściej niż 10 razy na sekundę. Throttle odpowiada na pytanie: „uruchamiać to regularnie, ale nie częściej niż co N ms”.
Kiedy stosować debounce
Debounce jest właściwym wyborem, gdy liczy się wyłącznie końcowa wartość po zakończeniu czynności przez użytkownika. Typowe przypadki to pole wyszukiwania (wysłanie żądania API po przerwie w pisaniu), handler zmiany rozmiaru okna (ponowne obliczenie układu po zakończeniu zmiany rozmiaru) oraz walidacja pola formularza sprawdzająca dane na serwerze (odczekanie na pełne dane przed walidacją).
Kiedy stosować throttle
Throttle jest właściwym wyborem, gdy potrzebne są regularne aktualizacje podczas ciągłej aktywności. Typowe przypadki to handler pozycji przewijania (aktualizowanie paska postępu czytania lub przyklejonego nagłówka z częstotliwością najwyżej 30 kl./s), śledzenie ruchu myszy (rejestrowanie pozycji kursora na potrzeby analityki) oraz handlery zdarzeń przeciągania (płynne aktualizowanie pozycji przeciąganego elementu bez zalewania aplikacji zdarzeniami).
Naiwne implementacje mają pułapki
Pisanie debounce lub throttle od zera bez pełnego zrozumienia ich działania prowadzi do błędów, takich jak pominięcie ostatniego zdarzenia (trailing edge), wywoływanie funkcji na niewłaściwych krawędziach lub nieusuwanie timerów przy odmontowaniu komponentu. Zazwyczaj lepiej korzystać ze sprawdzonych w praktyce implementacji z bibliotek takich jak lodash, które poprawnie obsługują wszystkie przypadki brzegowe.
lodash.debounce i lodash.throttle
Lodash udostępnia funkcje _.debounce(fn, wait) i _.throttle(fn, wait) z opcjami określającymi zachowanie na leading i trailing edge. Zwrócona funkcja ma metodę .cancel(), która anuluje oczekujące wywołanie, oraz metodę .flush(), która wykonuje je natychmiast. W React funkcje te należy opakować w useRef, aby uniknąć ich ponownego tworzenia podczas ponownego renderowania.
Budżet wydajności
Nawet 50 dodatkowych ponownych renderowań React na sekundę spowodowanych handlerem scroll bez throttle może zużywać znaczną ilość procesora, szczególnie na słabszych urządzeniach mobilnych. Budżet jednej klatki wynoszący 16 ms (60 kl./s) oznacza, że każde ponowne renderowanie musi zakończyć się w czasie krótszym niż 16 milisekund, aby uniknąć pomijania klatek. Debounce i throttle to pierwsza linia obrony przed problemami z płynnością animacji.
Handler zdarzenia a aktualizacja stanu
Nie każdy handler zdarzenia o wysokiej częstotliwości wymaga debounce. Jeśli handler tylko odczytuje wartość, nie aktualizując stanu ani nie wywołując API — na przykład zapisuje ostatnią pozycję myszy w ref — debounce nie jest potrzebny. Debounce lub throttle należy stosować wyłącznie do handlerów uruchamiających kosztowne operacje: aktualizacje stanu, wywołania API lub pomiary DOM.
Anulowanie funkcji objętych debounce
Po odmontowaniu komponentu każde oczekujące wywołanie objęte debounce powinno zostać anulowane, aby zapobiec aktualizacji stanu po odmontowaniu. Jeśli do przechowywania funkcji objętej debounce używany jest useRef, w funkcji cleanup useEffect należy wywołać debouncedFn.cancel(). Funkcje objęte debounce w Lodash udostępniają tę metodę właśnie w tym celu.
Zastosowanie debounce a throttle
Jakiej techniki należy użyć, aby wysłać żądanie API, gdy użytkownik przestanie pisać w polu wyszukiwania?
Podsumowanie lekcji: debounce i throttle
Zdarzenia o wysokiej częstotliwości, takie jak keypress, scroll i resize, mogą powodować problemy z wydajnością, jeśli handlery są uruchamiane przy każdym zdarzeniu. Debounce czeka na ciszę i najlepiej sprawdza się w polach wyszukiwania oraz handlerach zmiany rozmiaru. Throttle ogranicza częstotliwość i najlepiej sprawdza się przy przewijaniu oraz przeciąganiu. Należy używać implementacji Lodash przechowywanych w refach i zawsze anulować je przy odmontowaniu komponentu.
Ucz się React dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 88
- Lekcje
- 324
Często zadawane pytania
Czy lekcja „Dlaczego debounce i throttle są ważne w interfejsach” jest bezpłatna?
Tak — pełny tekst „Dlaczego debounce i throttle są ważne w interfejsach” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu React Academy, przejdź na CoddyKit PRO. Kurs React Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Dlaczego debounce i throttle są ważne w interfejsach”?
Zrozumieć koszt wydajnościowy nieograniczonych obsługiwaczy klawiszy, przewijania i zmiany rozmiaru oraz wiedzieć, kiedy stosować każde rozwiązanie Ćwiczysz React Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć React Academy?
Nie wymagamy żadnego doświadczenia. React Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Dlaczego debounce i throttle są ważne w interfejsach”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji React Academy?
Tak. Każda lekcja React Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Dlaczego debounce i throttle są ważne w interfejsach
- Implementowanie własnego hooka useDebounce
- Implementowanie własnego hooka useThrottle
- Zastosowania praktyczne: wyszukiwanie, przewijanie, zmiana rozmiaru