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

JavaScript jest często czynnikiem wywołującym zmiany wizualne. Czasami jest to bezpośrednio spowodowane manipulacją stylem, a czasem obliczeniami, które powodują zmianę wyglądu, np. wyszukiwanie lub sortowanie niektórych danych. Niewłaściwie działający kod JavaScript lub jego długi czas działania mogą być częstą przyczyną problemów z wydajnością i staraj się zminimalizować jego wpływ na działanie kodu.

Zmiana DOM przez dodawanie i usuwanie elementów, zmianę atrybutów, klas lub animacji spowoduje ponowne obliczenie stylów elementów przez przeglądarkę, a w wielu przypadkach również zmianę układu (lub przeformatowania) strony lub jej części. Jest to tzw. obliczanie stylu obliczonego.

Pierwsza część stylów obliczeniowych to utworzenie zestawu selektorów dopasowywania, czyli zasadniczo przeglądarka ustala, które klasy, pseudoselektory i identyfikatory mają zastosowanie do danego elementu.

Druga część procesu obejmuje wszystkie reguły stylów z selektorów dopasowania i ustala ostateczne style elementu.

Podsumowanie

  • jak obniżenie kosztów obliczania stylów może zmniejszyć czas oczekiwania na interakcję,
  • Zmniejsz złożoność selektorów – użyj metodologii skoncentrowanej na klasach (np. BEM).
  • Zmniejsz liczbę elementów, dla których należy obliczać styl.

Czas ponownego obliczania stylu i opóźnienie interakcji

Interakcja z następnym wyrenderowaniem (INP) to skoncentrowane na użytkownikach dane o skuteczności środowiska wykonawczego, które pozwalają ocenić ogólną responsywność strony w odniesieniu do danych wejściowych użytkownika. Gdy czas oczekiwania na interakcję jest oceniany na podstawie tych danych, jest to czas od chwili interakcji użytkownika ze stroną do momentu, gdy przeglądarka wyświetli kolejną klatkę z odpowiednimi zmianami wizualnymi w interfejsie.

Ważnym składnikiem interakcji jest czas potrzebny do wyrenderowania następnej klatki. Renderowanie w celu zaprezentowania następnej klatki składa się z wielu części, w tym z obliczenia stylów stron bezpośrednio przed układem, malowaniem i komponowaniem. Chociaż ten artykuł skupia się wyłącznie na kosztach obliczania stylów, należy podkreślić, że ograniczenie jakiejkolwiek części fazy renderowania powiązanej z interakcją zmniejszy całkowite opóźnienie (uwzględnione są obliczenia stylu).

Zmniejszenie złożoności selektorów

W najprostszym przypadku możesz odwołać się do elementu w CSS za pomocą samej klasy:

.title {
  /* styles */
}

Jednak w miarę rozwoju projektu prawdopodobnie powstanie bardziej złożony CSS, przez co możesz otrzymać selektory podobne do tych:

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

Aby dowiedzieć się, jak te style mają się do strony, przeglądarka musi zadać pytanie: „Czy jest to element z klasą title, który ma element nadrzędny (minus n-ty element podrzędny i 1) o klasie box”. Ustalenie tego może zająć dużo czasu w zależności od używanego selektora oraz przeglądarki, której dotyczy problem. Zamierzone działanie selektora można zamiast tego zmienić na klasę:

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

Z nazwą zajęć możesz zrezygnować, ale przeglądarka jest znacznie prostsza. Aby na przykład wiedzieć, że element jest ostatnim w swoim typie, w poprzedniej wersji przeglądarka musi najpierw wiedzieć wszystko o wszystkich pozostałych elementach i o tym, czy są to elementy występujące po nim, czyli nth-last-child. Może to być potencjalnie droższe niż dopasowanie selektora do elementu ze względu na dopasowanie jego klasy.

Zmniejsz liczbę elementów, do których nadaje się styl

Kolejnym czynnikiem wpływającym na wydajność, który jest zwykle ważniejszym czynnikiem w przypadku wielu aktualizacji stylu, jest ogromna ilość pracy, jaką trzeba wykonać przy zmianie elementu.

Ogólnie rzecz biorąc, najgorszym kosztem obliczenia stylu obliczonego elementów jest liczba elementów pomnożona przez liczbę selektora, ponieważ każdy element należy sprawdzić co najmniej raz pod kątem każdego stylu, aby zobaczyć, czy jest zgodny.

Obliczenia stylu często mogą być kierowane bezpośrednio na kilka elementów, zamiast unieważniać całą stronę. W nowoczesnych przeglądarkach problem ten bywa mniejszy, ponieważ nie musi ono sprawdzać wszystkich elementów, na które może mieć wpływ zmiana. Starsze przeglądarki nie są jednak w pełni zoptymalizowane pod kątem takich zadań. Gdy tylko jest to możliwe, zmniejsz liczbę nieprawidłowych elementów.

Mierz koszt ponownego obliczania stylu

Jednym ze sposobów sprawdzenia kosztu ponownego obliczenia stylu jest użycie panelu wydajności w Narzędziach deweloperskich w Chrome. Aby rozpocząć, otwórz Narzędzia deweloperskie, przejdź na kartę Wydajność, kliknij Zarejestruj i wejdź na stronę. Po zatrzymaniu nagrywania zobaczysz coś takiego:

Narzędzia deweloperskie z obliczeniami stylu.

Pasek u góry to miniaturowy wykres płomieniowy, który również zlicza klatki na sekundę. Im bliżej dolnej części paska wykonywana jest czynność, tym szybsze klatki są malowane przez przeglądarkę. Jeśli wykres płomieniowy wyrównuje się u góry i ma nad nim czerwone paski, oznacza to, że masz zadanie, które powoduje wyświetlanie długich klatek.

Powiększenie obszaru błędu w Narzędziach deweloperskich w Chrome w podsumowaniu aktywności w wypełnionym panelu wydajności w Narzędziach deweloperskich w Chrome.

Jeśli podczas interakcji, takiej jak przewijanie, masz długotrwałą klatkę, należy ją dokładniej sprawdzić. Jeśli masz duży fioletowy blok, powiększ aktywność i wybierz dowolną pracę z etykietą Ponownie oblicz styl, aby uzyskać więcej informacji o potencjalnie kosztownych obliczeniach.

Uzyskiwanie szczegółów długo trwających obliczeń stylu, w tym istotnych informacji, takich jak liczba elementów, na które wpływa ponowne obliczanie stylu.

Jest to długotrwała operacja przeliczania stylów, która trwa nieco ponad 25 ms.

Jeśli klikniesz samo zdarzenie, otrzymasz stos wywołań. Jeśli renderowanie było wynikiem interakcji użytkownika, będzie wskazywane miejsce w kodzie JavaScript, które powoduje zmianę stylu. Poza tym otrzymujesz też informacje o liczbie elementów, na które miała wpływ zmiana (w tym przypadku o niemal 900 elementów), oraz o czasie potrzebnym na obliczenie stylu. Możesz wykorzystać te informacje, aby znaleźć rozwiązanie w kodzie.

Użyj bloku, elementu, modyfikatora

W przypadku kodowania BEM (blokowanie, element, modyfikator) wykorzystuje się powyższe korzyści w zakresie wydajności dopasowywania selektorów, ponieważ zaleca się, aby wszystko miało jedną klasę, a jeśli potrzebna jest hierarchia, która również jest wpisana w nazwę klasy:

.list {
  /* Styles */
}

.list__list-item {
  /* Styles */
}

Jeśli potrzebujesz modyfikatora, tak jak w przykładzie powyżej, gdzie chcemy zrobić coś specjalnego w przypadku ostatniego dziecka, możesz go dodać w następujący sposób:

.list__list-item--last-child {
  /* Styles */
}

Jeśli szukasz dobrego sposobu na uporządkowanie kodu CSS, zacznij od BEM, zarówno z perspektywy struktury, jak i z powodu uproszczeń wyszukiwania stylów, które promuje ta metodologia.

Jeśli nie podoba Ci się model BEM, istnieją inne sposoby podejścia do CSS, ale aspekty wydajności należy brać pod uwagę razem z ergonomią stosowanego podejścia.

Zasoby

Baner powitalny z serialu Unsplash, autor: Markus Spiske.