Zapisywanie motywu i zapobieganie migotaniu
Zapisywać preferencje motywu w localStorage i wstrzykiwać skrypt blokujący, który ustawia motyw przed załadowaniem Reacta
Zapisywanie motywu i zapobieganie migotaniu 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.
Problem mignięcia niewłaściwego motywu
Podczas ładowania strony React musi pobrać, sparsować i wykonać JavaScript, zanim będzie mógł odczytać localStorage i zastosować właściwy motyw. W tym czasie przeglądarka renderuje stronę z użyciem stylów domyślnych. Jeśli użytkownik preferuje tryb ciemny, a motywem domyślnym jest jasny, przed skorygowaniem motywu zobaczy krótkie białe mignięcie.
Rozwiązanie z blokującym skryptem
Rozwiązaniem jest osadzony skrypt umieszczony w document head, który działa synchronicznie przed wykonaniem jakiegokolwiek innego kodu. Skrypt natychmiast odczytuje localStorage i ustawia data-theme na document.documentElement. Ponieważ jest skryptem blokującym, przeglądarka ustawia atrybut przed wyświetleniem jakiejkolwiek treści.
Dlaczego wymagane jest blokowanie
Skrypty asynchroniczne lub odroczone są uruchamiane po sparsowaniu kodu HTML, a potencjalnie także po pierwszym wyświetleniu strony. Niweczy to cały cel tego rozwiązania. Blokujący skrypt osadzony bezpośrednio w dokumencie nie może mieć atrybutów async ani defer i nie może być ładowany z zewnętrznego pliku. Skrypt musi być bardzo mały, aby ograniczyć koszt wydajnościowy.
Zawartość skryptu osadzonego
Skrypt blokujący jest minimalny: odczytuje localStorage.getItem('theme'), sprawdza window.matchMedia('(prefers-color-scheme: dark)').matches jako rozwiązanie zastępcze, a następnie wywołuje document.documentElement.setAttribute('data-theme', theme). Należy opakować go w try-catch na wypadek, gdyby localStorage był niedostępny w trybie prywatnym.
Implementacja w Next.js
W Next.js należy użyć komponentu Script z next/script z ustawieniem strategy="beforeInteractive" w pliku _document.js. Strategia beforeInteractive wstrzykuje skrypt do kodu HTML strony przed uruchomieniem jakiegokolwiek JavaScriptu strony, zapewniając takie samo blokujące działanie w procesie budowania Next.js.
Implementacja w Vite i CRA
W projekcie Vite lub Create React App należy bezpośrednio edytować plik index.html i umieścić znacznik osadzonego skryptu w sekcji head, przed innymi skryptami. Ponieważ index.html jest punktem wejścia przeglądarki, skrypt uruchamia się przed uruchomieniem Reacta. Należy zadbać o zwięzłość skryptu, aby jego rozmiar nie przekraczał 100 bajtów.
Rozwiązanie SSR z użyciem pliku cookie lub nagłówka
W aplikacji renderowanej po stronie serwera serwer może odczytać motyw z pliku cookie przesłanego wraz z żądaniem. Następnie serwer ustawia data-theme w wygenerowanym kodzie HTML przed wysłaniem go do przeglądarki. Eliminuje to całkowicie mignięcie po stronie klienta, ponieważ właściwy motyw znajduje się już w pierwszym bajcie kodu HTML.
Kompletny przebieg bez mignięcia
Kompletny przebieg wygląda następująco: przeglądarka pobiera kod HTML, parser napotyka blokujący skrypt osadzony bezpośrednio w dokumencie, skrypt odczytuje localStorage i ustawia data-theme, parser kontynuuje pracę, strona jest wyświetlana z właściwym motywem, a React przeprowadza hydratację i odczytuje ten sam motyw z localStorage. Użytkownik od samego początku widzi jeden spójny motyw.
Testowanie zapobiegania mignięciu
Aby sprawdzić, czy rozwiązanie działa, należy otworzyć Chrome DevTools, przejść do karty Network i ustawić ograniczenie sieci na Slow 3G. Następnie należy przeładować stronę. Jeśli podczas ładowania widoczna jest zmiana motywu, mignięcie nie zostało usunięte. Po dodaniu skryptu blokującego pierwsze wyświetlenie powinno już przedstawiać właściwy motyw, nawet przy wolnym połączeniu.
Ryzyko niezgodności podczas hydratacji
Jeśli początkowy stan Reacta ma domyślnie wartość jasną, ale skrypt blokujący ustawił przed hydratacją wartość ciemną, React może zgłosić ostrzeżenie o niezgodności podczas hydratacji. Należy temu zapobiec, inicjalizując stan motywu Reacta również przez odczyt localStorage podczas pierwszego renderowania, aby kod HTML wygenerowany przez Reacta odpowiadał stanowi DOM ustawionemu przez skrypt blokujący.
Mignięcie w Storybooku i środowiskach testowych
Storybook i środowiska testowe nie wczytują pliku index.html, więc skrypt blokujący nigdy się w nich nie uruchamia. Należy udostępnić dekorator lub konfigurację testów, która ustawia domyślny atrybut data-theme w tych środowiskach. Zapobiega to mylącym niespójnościom wizualnym podczas tworzenia komponentów w izolacji.
Technika zapobiegania mignięciu
Jakiego rodzaju skryptu należy użyć w sekcji head dokumentu, aby zapobiec mignięciu niewłaściwego motywu?
Podsumowanie lekcji: zachowywanie motywu i zapobieganie mignięciu
Mignięciu niewłaściwego motywu należy zapobiegać przez wstrzyknięcie niewielkiego, blokującego skryptu osadzonego bezpośrednio w sekcji head dokumentu. Skrypt odczytuje localStorage i ustawia data-theme przed pierwszym wyświetleniem strony. W Next.js należy użyć strategy="beforeInteractive", a w Vite/CRA dodać skrypt bezpośrednio do pliku index.html. Aplikacje SSR mogą odczytać cookie i ustawić motyw po stronie serwera.
Często zadawane pytania
Czy lekcja „Zapisywanie motywu i zapobieganie migotaniu” jest bezpłatna?
Tak — pełny tekst „Zapisywanie motywu i zapobieganie migotaniu” 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 „Zapisywanie motywu i zapobieganie migotaniu”?
Zapisywać preferencje motywu w localStorage i wstrzykiwać skrypt blokujący, który ustawia motyw przed załadowaniem Reacta Ć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 „Zapisywanie motywu i zapobieganie migotaniu”?
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
- Wykrywanie schematu kolorów systemu
- Zmienne CSS do przełączania motywów
- React Context do przechowywania stanu motywu
- Zapisywanie motywu i zapobieganie migotaniu