Unikanie przeciążenia layoutu i migotania wizualnego
Rozpoznawać sytuacje, w których useEffect powoduje widoczne migotanie, i zastępować go useLayoutEffect, aby je usunąć
Unikanie przeciążenia layoutu i migotania wizualnego to bezpłatna lekcja React Academy na CoddyKit. To lekcja 4 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.
Czym jest layout thrashing
Layout thrashing występuje, gdy JavaScript naprzemiennie odczytuje właściwości DOM i zapisuje dane w DOM w pętli. Każdy odczyt następujący po zapisie zmusza przeglądarkę do synchronicznego ponownego obliczenia layoutu w celu zwrócenia dokładnej wartości. Może to zmienić pojedyncze obliczenie layoutu w dziesiątki obliczeń, poważnie pogarszając wydajność.
Jak grupowanie aktualizacji pomaga w React
React grupuje wszystkie wywołania setState wykonywane w obsłudze zdarzeń i efektach w jedno ponowne renderowanie. To naturalne grupowanie zapobiega wzorcowi odczyt-zapis-odczyt, który powoduje layout thrashing w ramach jednego cyklu renderowania. W React 18 grupowanie obejmuje również asynchroniczne funkcje zwrotne i obiekty Promise, ograniczając layout thrashing wynikający z równoczesnych aktualizacji stanu.
Kiedy w useEffect pojawia się migotanie
Migotanie pojawia się, gdy useEffect odczytuje DOM, aktualizuje stan, wywołuje ponowne renderowanie, a przeglądarka maluje ekran dwukrotnie: raz ze stanem początkowym i raz ze skorygowanym stanem. Pierwsze malowanie miga przez krótką chwilę, zanim zostanie zastąpione. Jest to najbardziej widoczne w przypadku efektów, które dostosowują właściwości układu, takie jak wysokość, szerokość lub położenie.
Diagnozowanie migotania za pomocą DevTools
Otwórz Chrome DevTools, przejdź do karty Rendering (za pomocą menu z trzema kropkami w sekcji More tools) i włącz opcję „Paint flashing”. Obszary ponownie malowane zostaną wyróżnione na zielono. Jeśli zobaczysz, że komponent miga przy pierwszym renderowaniu, a następnie natychmiast jest ponownie malowany w innym układzie, potwierdza to podwójne malowanie spowodowane aktualizacją stanu sterowaną przez useEffect.
Usuwanie migotania przez przejście na useLayoutEffect
Przenieś odczyty DOM i wynikające z nich aktualizacje stanu z useEffect do useLayoutEffect. Ten sam pomiar i aktualizacja stanu zachodzą teraz synchronicznie przed malowaniem, React ponownie renderuje i zatwierdza zmiany w ramach tej samej fazy, a przeglądarka maluje ekran tylko raz, wyświetlając końcowy, prawidłowy stan. Zielone migotanie w DevTools znika.
Wzorzec pojedynczego malowania
Wzorzec eliminujący migotanie wygląda tak: odczytaj DOM w useLayoutEffect, wywołaj setState z wynikiem pomiaru, React synchronicznie renderuje ponownie, zatwierdza skorygowany DOM, a przeglądarka maluje ekran raz, wyświetlając końcowy rezultat. Jest to standardowy wzorzec stosowany przy pozycjonowaniu tooltipów, określaniu przesunięć przyklejonych nagłówków oraz konfiguracji animacji.
Prawidłowe przypadki użycia useEffect
Zdecydowana większość efektów powinna znajdować się w useEffect: pobieranie danych (migotanie związane z ładowaniem jest dopuszczalne i oczekiwane), subskrypcje zdarzeń lub strumieni, rejestrowanie logów i analityka, liczniki czasu oraz każdy efekt, który nie wpływa natychmiast na widoczny układ. Nadmierne używanie useLayoutEffect tam, gdzie wystarczyłby useEffect, jest antywzorcem pogarszającym wydajność.
Prawidłowe przypadki użycia useLayoutEffect
Należy rezerwować useLayoutEffect dla pomiarów DOM, które wpływają z powrotem na wynik wizualny: pozycji tooltipów, logiki zależnej od rozmiaru elementu, przywracania pozycji przewijania oraz konfiguracji animacji odczytującej początkowe wymiary. Wyraźnym sygnałem wskazującym na konieczność przejścia jest widoczne, trwające jedną klatkę migotanie nieprawidłowego układu przy pierwszym renderowaniu.
Porównanie useEffect i useLayoutEffect w kodzie
Sygnatury obu hooków są identyczne: useLayoutEffect(callback, deps) vs useEffect(callback, deps). Jedyna różnica dotyczy momentu wykonania funkcji zwrotnej. Można przełączać się między nimi, zmieniając w kodzie jedno słowo. Należy zacząć od useEffect i przejść na useLayoutEffect dopiero po potwierdzeniu migotania.
Łączenie obu hooków w jednym komponencie
Używanie obu hooków w tym samym komponencie do obsługi różnych zagadnień jest prawidłowe i często stosowane. Na przykład komponent wykresu może używać useLayoutEffect, aby zmierzyć szerokość kontenera i synchronicznie ustawić viewBox SVG, a następnie używać useEffect do asynchronicznego pobierania danych wykresu. Każdy hook obsługuje ten aspekt, dla którego czas wykonania ma znaczenie.
Testowanie podwójnego malowania
Oprócz migotania podczas malowania w DevTools można dodać licznik w konsoli wewnątrz komponentu, aby zliczać renderowania. Jeśli komponent loguje „render” dwukrotnie przy pierwszym montowaniu — raz ze stanem początkowym i raz ze skorygowanym pomiarem — mamy do czynienia z podwójnym malowaniem. Przeniesienie pomiaru do useLayoutEffect powinno ograniczyć wynik do jednego renderowania zarejestrowanego po zamontowaniu (nie licząc podwójnego renderowania w Strict Mode).
Kiedy wybrać useLayoutEffect zamiast useEffect
W którym przypadku właściwym powodem użycia useLayoutEffect zamiast useEffect jest dany scenariusz?
Podsumowanie lekcji: Layout thrashing i migotanie wizualne
Layout thrashing wynika z naprzemiennego odczytywania i zapisywania DOM. Grupowanie operacji przez React zapobiega większości takich przypadków podczas renderowania. Migotanie pojawia się, gdy useEffect mierzy DOM i aktualizuje stan, powodując dwa malowania. Aby usunąć migotanie, należy przenieść pomiary DOM do useLayoutEffect. W pozostałych przypadkach należy domyślnie używać useEffect: do pobierania danych, subskrypcji, rejestrowania logów i liczników czasu.
Często zadawane pytania
Czy lekcja „Unikanie przeciążenia layoutu i migotania wizualnego” jest bezpłatna?
Tak — pełny tekst „Unikanie przeciążenia layoutu i migotania wizualnego” 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 „Unikanie przeciążenia layoutu i migotania wizualnego”?
Rozpoznawać sytuacje, w których useEffect powoduje widoczne migotanie, i zastępować go useLayoutEffect, aby je usunąć Ć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 4 z 4.
Ile czasu zajmuje lekcja „Unikanie przeciążenia layoutu i migotania wizualnego”?
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
- Faza renderowania i zatwierdzanie DOM
- Kiedy uruchamia się useLayoutEffect, a kiedy useEffect
- Pomiar elementów DOM za pomocą useLayoutEffect
- Unikanie przeciążenia layoutu i migotania wizualnego