Zmniejsz zakres i złożoność obliczeń dotyczących stylu

JavaScript często wywołuje zmiany wizualne. Czasami wprowadza te zmiany bezpośrednio przez manipulowanie stylami, a czasami przez obliczenia, które powodują zmiany wizualne, takie jak wyszukiwanie lub sortowanie danych. Źle zaplanowane lub długotrwałe działanie JavaScriptu może być częstą przyczyną problemów z wydajnością. Warto zminimalizować jego wpływ, gdzie tylko się da.

Obliczanie stylu

Zmiana DOM przez dodawanie i usuwanie elementów, zmianę atrybutów, klas lub odtwarzanie animacji powoduje, że przeglądarka ponownie oblicza style elementów, a w wielu przypadkach także układ części lub całości strony. Ten proces nazywa się obliczaniem stylu.

Przeglądarka rozpoczyna obliczanie stylów, tworząc zestaw pasujących selektorów, aby określić, które klasy, pseudoselektory i identyfikatory mają zastosowanie do danego elementu. Następnie przetwarza reguły stylów z pasujących selektorów i określa, jakie style końcowe ma element.

Rola ponownego obliczania stylów w opóźnieniu interakcji

Interakcja do kolejnego wyrenderowania (INP) to zorientowany na użytkownika wskaźnik skuteczności w czasie działania, który ocenia ogólną responsywność strony na dane wejściowe użytkownika. Mierzy opóźnienie interakcji od momentu, w którym użytkownik wchodzi w interakcję ze stroną, do momentu, w którym przeglądarka wyrenderuje kolejną klatkę z odpowiednimi zmianami wizualnymi w interfejsie.

Ważnym elementem interakcji jest czas potrzebny na wyrenderowanie kolejnej klatki. Praca związana z renderowaniem, która jest wykonywana w celu wyświetlenia następnej klatki, składa się z wielu części, w tym z obliczeń stylów strony, które są wykonywane tuż przed pracą związaną z układem, rysowaniem i komponowaniem. Ten przewodnik koncentruje się na kosztach obliczania stylu, ale zmniejszenie dowolnej części całkowitego czasu renderowania interakcji zmniejsza też jej całkowite opóźnienie.

Zmniejsz złożoność selektorów

Uproszczenie selektorów CSS może przyspieszyć obliczanie stylów strony. Najprostsze selektory odwołują się do elementu w arkuszu CSS tylko za pomocą nazwy klasy:

.title {
  /* styles */
}

Jednak w miarę rozwoju projektu prawdopodobnie będziesz potrzebować bardziej złożonego kodu CSS i możesz skończyć z selektorami podobnymi do tego:

.box:nth-last-child(-n+1) .title {
  /* styles */
}

Aby określić, jak te style mają być stosowane na stronie, przeglądarka musi zadać pytanie: „Czy to jest element z klasą title, którego elementem nadrzędnym jest klasa box, która jest n-tym dzieckiem elementu nadrzędnego pomniejszonym o 1?” Określenie tego może zająć przeglądarce trochę czasu. Aby to uprościć, możesz zmienić selektor na bardziej szczegółową nazwę klasy:

.final-box-title {
  /* styles */
}

Te nazwy klas zastępczych mogą wydawać się dziwne, ale znacznie ułatwiają pracę przeglądarce. W poprzedniej wersji, aby przeglądarka wiedziała, że element jest ostatnim elementem danego typu, musi najpierw poznać wszystkie inne elementy, aby określić, czy po nim występują elementy, które mogą być nth-last-child. Może to być znacznie bardziej kosztowne obliczeniowo niż dopasowywanie selektora do elementu wyłącznie na podstawie jego nazwy klasy.

Zmniejsz liczbę elementów, do których stosowane są style.

Kolejnym aspektem wydajności, często ważniejszym niż złożoność selektora, jest ilość pracy, jaką trzeba wykonać, gdy element ulegnie zmianie.

Ogólnie rzecz biorąc, koszt obliczania stylu elementów obliczonych w najgorszym przypadku to liczba elementów pomnożona przez liczbę selektorów, ponieważ przeglądarka musi sprawdzić każdy element co najmniej raz pod kątem każdego stylu, aby zobaczyć, czy pasuje.

Obliczenia stylu mogą być kierowane bezpośrednio na kilka elementów zamiast unieważniać całą stronę. W nowoczesnych przeglądarkach ten problem występuje rzadziej, ponieważ nie zawsze muszą one sprawdzać wszystkie elementy, na które może wpłynąć zmiana. Starsze przeglądarki nie zawsze są zoptymalizowane pod kątem takich zadań. W miarę możliwości zmniejsz liczbę unieważnionych elementów.

Sprawdzanie kosztu przeliczenia stylu

Istnieje kilka sposobów pomiaru kosztu ponownego obliczania stylów w przeglądarce. Każda z nich zależy od tego, czy chcesz mierzyć czas w przeglądarce w środowisku programistycznym, czy też chcesz mierzyć, ile czasu zajmuje ten proces prawdziwym użytkownikom w Twojej witrynie.

Pomiar kosztu ponownego obliczania stylu w Narzędziach deweloperskich w Chrome

Jednym ze sposobów pomiaru kosztu ponownego obliczania stylów jest użycie panelu wydajności w Narzędziach deweloperskich w Chrome. Aby rozpocząć:

  1. Otwórz Narzędzia deweloperskie.
  2. Otwórz kartę Skuteczność.
  3. Zaznacz pole wyboru Statystyki selektora (opcjonalnie).
  4. Kliknij Nagraj.
  5. Wejdź w interakcję ze stroną.

Gdy zatrzymasz nagrywanie, zobaczysz obraz podobny do tego:

Narzędzia deweloperskie pokazujące obliczenia stylów.
Raport z Narzędzi deweloperskich pokazujący obliczenia stylu.

Pasek u góry to miniaturowy wykres płomieniowy, który pokazuje też liczbę klatek na sekundę. Im bliżej dolnej krawędzi paska znajduje się aktywność, tym szybciej przeglądarka renderuje klatki. Jeśli u góry wykresu płomieniowego widzisz czerwone paski, oznacza to, że masz zadania, które powodują długotrwałe klatki.

Powiększenie obszaru problemowego w Narzędziach deweloperskich w Chrome w podsumowaniu aktywności wypełnionego panelu wydajności w Narzędziach deweloperskich w Chrome.
Długotrwałe klatki w podsumowaniu aktywności Narzędzi deweloperskich.

Długotrwałe klatki podczas interakcji, takich jak przewijanie, wymagają dokładniejszego przyjrzenia się. Jeśli widzisz duży fioletowy blok, powiększ aktywność i wybierz dowolną pracę oznaczoną jako Recalculate Style, aby uzyskać więcej informacji o potencjalnie kosztownych działaniach związanych z ponownym obliczaniem stylu.

Uzyskiwanie szczegółów długotrwałych obliczeń stylu, w tym ważnych informacji, takich jak liczba elementów, na które wpływa ponowne obliczenie stylu.
Długotrwałe ponowne obliczanie stylu trwające nieco ponad 25 ms w podsumowaniu Narzędzi deweloperskich.

Kliknięcie zdarzenia powoduje wyświetlenie jego stosu wywołań. Jeśli renderowanie zostało spowodowane interakcją użytkownika, wskazuje skrypt JavaScript, który wywołał zmianę stylu. Wyświetla też liczbę elementów, na które wpływa zmiana – w tym przypadku nieco ponad 900 – oraz czas obliczania stylu. Na podstawie tych informacji możesz zacząć szukać rozwiązania w kodzie.

Jeśli przed wykonaniem śledzenia w ustawieniach panelu wydajności zaznaczysz pole wyboru Statystyki selektora, w dolnym panelu śledzenia pojawi się dodatkowa karta o tej samej nazwie.

Tabela statystyk selektora CSS wyświetlana w panelu wydajności Narzędzi deweloperskich w Chrome. Ta tabela zawiera nagłówki i odpowiadające im dane dotyczące takich elementów jak czas, próby dopasowania, liczba dopasowań, odsetek węzłów niedopasowanych, selektory i arkusz stylów, w którym można je znaleźć.
Tabela statystyk selektora widoczna na panelu Wydajność w Narzędziach deweloperskich w Chrome.

Ten panel zawiera przydatne dane o względnym koszcie każdego selektora, co pozwala identyfikować kosztowne selektory CSS.

Więcej informacji znajdziesz w dokumentacji statystyk selektorów CSS.

Pomiar kosztu ponownego obliczania stylu w przypadku rzeczywistych użytkowników

Jeśli chcesz dowiedzieć się, ile czasu zajmuje ponowne obliczenie stylu w przypadku prawdziwych użytkowników Twojej witryny, interfejs Long Animation Frames API udostępnia Ci narzędzia, które Ci to umożliwią. Dane z tego interfejsu API zostały dodane do biblioteki JavaScript, w tym czas ponownego obliczania stylu.web-vitals

Jeśli podejrzewasz, że opóźnienie prezentacji interakcji jest głównym czynnikiem wpływającym na INP strony, musisz sprawdzić, ile czasu zajmuje ponowne obliczanie stylów na stronie. Więcej informacji znajdziesz w artykule o pomiarze czasu ponownego obliczania stylu w terenie.

Zasoby