Zwiększ szybkość aplikacji internetowych, rozumiejąc potok renderowania przeglądarki i jak JavaScript może spowalniać wydajność. Naucz się optymalizacji dla płynnego doświadczenia użytkownika.
Opanowanie potoku renderowania przeglądarki: dogłębna analiza wpływu JavaScript na wydajność
W cyfrowym świecie szybkość to nie tylko funkcja; to fundament wspaniałego doświadczenia użytkownika. Wolna, niereagująca strona internetowa może prowadzić do frustracji użytkowników, zwiększonych współczynników odrzuceń i ostatecznie negatywnego wpływu na cele biznesowe. Jako deweloperzy internetowi jesteśmy architektami tego doświadczenia, a zrozumienie podstawowych mechanizmów, za pomocą których przeglądarka zamienia nasz kod w wizualną, interaktywną stronę, jest sprawą nadrzędną. Ten proces, często owiany tajemnicą, jest znany jako potok renderowania przeglądarki.
W sercu nowoczesnej interaktywności internetowej leży JavaScript. To język, który ożywia nasze statyczne strony, umożliwiając wszystko, od dynamicznych aktualizacji treści po złożone aplikacje jednostronicowe (single-page applications). Jednak z wielką mocą wiąże się wielka odpowiedzialność. Niezoptymalizowany JavaScript jest jednym z najczęstszych winowajców słabej wydajności sieciowej. Może on przerywać, opóźniać lub zmuszać potok renderowania przeglądarki do wykonywania kosztownej, zbędnej pracy, prowadząc do znienawidzonego „zacinania się” (jank) – rwanych animacji, powolnych reakcji na działania użytkownika i ogólnego wrażenia ociężałości.
Ten kompleksowy przewodnik jest przeznaczony dla deweloperów front-end, inżynierów wydajności i wszystkich pasjonatów budowania szybszej sieci. Zdemistyfikujemy potok renderowania przeglądarki, dzieląc go na zrozumiałe etapy. Co ważniejsze, rzucimy światło na rolę JavaScriptu w tym procesie, badając dokładnie, jak może stać się on wąskim gardłem wydajności i, co kluczowe, co możemy zrobić, aby to złagodzić. Na koniec będziesz wyposażony w wiedzę i praktyczne strategie do pisania bardziej wydajnego JavaScriptu i dostarczania płynnego, zachwycającego doświadczenia użytkownikom na całym świecie.
Plan działania sieci: dekonstrukcja potoku renderowania przeglądarki
Zanim zaczniemy optymalizować, musimy najpierw zrozumieć. Potok renderowania przeglądarki (znany również jako krytyczna ścieżka renderowania) to sekwencja kroków, które przeglądarka wykonuje, aby przekształcić napisany przez nas kod HTML, CSS i JavaScript w piksele na ekranie. Pomyśl o tym jak o wysoce wydajnej fabrycznej linii montażowej. Każde stanowisko ma określone zadanie, a wydajność całej linii zależy od tego, jak płynnie produkt przemieszcza się z jednego stanowiska na drugie.
Chociaż szczegóły mogą się nieznacznie różnić między silnikami przeglądarek (takimi jak Blink dla Chrome/Edge, Gecko dla Firefox i WebKit dla Safari), podstawowe etapy są koncepcyjnie takie same. Przejdźmy przez tę linię montażową.
Krok 1: Parsowanie - od kodu do zrozumienia
Proces rozpoczyna się od surowych, tekstowych zasobów: twoich plików HTML i CSS. Przeglądarka nie może z nimi pracować bezpośrednio; musi je sparsować do struktury, którą jest w stanie zrozumieć.
- Parsowanie HTML do DOM: Parser HTML przeglądarki przetwarza kod HTML, tokenizując go i budując z niego drzewiastą strukturę danych zwaną Document Object Model (DOM). DOM reprezentuje treść i strukturę strony. Każdy tag HTML staje się „węzłem” w tym drzewie, tworząc relację rodzic-dziecko, która odzwierciedla hierarchię twojego dokumentu.
- Parsowanie CSS do CSSOM: Równocześnie, gdy przeglądarka napotka CSS (czy to w tagu
<style>
, czy w zewnętrznym arkuszu stylów<link>
), parsuje go, tworząc CSS Object Model (CSSOM). Podobnie jak DOM, CSSOM to struktura drzewiasta, która zawiera wszystkie style powiązane z węzłami DOM, włączając w to domyślne style przeglądarki (user-agent styles) oraz twoje jawne reguły.
Kluczowa uwaga: CSS jest uważany za zasób blokujący renderowanie. Przeglądarka nie zrenderuje żadnej części strony, dopóki w pełni nie pobierze i nie sparsuje całego CSS. Dlaczego? Ponieważ musi znać ostateczne style dla każdego elementu, zanim będzie mogła określić, jak rozmieścić stronę. Niestylowana strona, która nagle zmienia swój wygląd, byłaby dla użytkownika nieprzyjemnym doświadczeniem.
Krok 2: Drzewo renderowania - wizualny plan
Gdy przeglądarka ma już zarówno DOM (treść), jak i CSSOM (style), łączy je, tworząc Drzewo renderowania. To drzewo jest reprezentacją tego, co faktycznie zostanie wyświetlone na stronie.
Drzewo renderowania nie jest kopią DOM jeden do jednego. Zawiera tylko te węzły, które są wizualnie istotne. Na przykład:
- Węzły takie jak
<head>
,<script>
czy<meta>
, które nie mają wizualnego odpowiednika, są pomijane. - Węzły, które są jawnie ukryte za pomocą CSS (np. z
display: none;
), również są pomijane w Drzewie renderowania. (Uwaga: elementy zvisibility: hidden;
są uwzględniane, ponieważ wciąż zajmują miejsce w układzie).
Każdy węzeł w Drzewie renderowania zawiera zarówno swoją treść z DOM, jak i obliczone style z CSSOM.
Krok 3: Układ (lub Reflow) - obliczanie geometrii
Po skonstruowaniu Drzewa renderowania przeglądarka wie już co ma renderować, ale nie gdzie ani jak duże. To jest zadanie etapu Układu. Przeglądarka przemierza Drzewo renderowania, zaczynając od korzenia, i oblicza precyzyjne informacje geometryczne dla każdego węzła: jego rozmiar (szerokość, wysokość) i pozycję na stronie względem viewportu.
Ten proces jest również znany jako Reflow (przeliczenie układu). Termin 'reflow' jest szczególnie trafny, ponieważ zmiana w jednym elemencie może mieć efekt kaskadowy, wymagając ponownego obliczenia geometrii jego dzieci, przodków i rodzeństwa. Na przykład, zmiana szerokości elementu nadrzędnego prawdopodobnie spowoduje reflow dla wszystkich jego potomków. To sprawia, że Układ jest potencjalnie bardzo kosztowną obliczeniowo operacją.
Krok 4: Malowanie - wypełnianie pikseli
Teraz, gdy przeglądarka zna strukturę, style, rozmiar i pozycję każdego elementu, nadszedł czas, aby przełożyć te informacje na rzeczywiste piksele na ekranie. Etap Malowania (lub Repaint - przemalowanie) polega na wypełnianiu pikseli dla wszystkich wizualnych części każdego węzła: kolorów, tekstu, obrazów, obramowań, cieni itp.
Aby uczynić ten proces bardziej wydajnym, nowoczesne przeglądarki nie malują po prostu na jednym płótnie. Często dzielą stronę na wiele warstw. Na przykład złożony element z transformacją CSS transform
lub element <video>
może zostać przeniesiony na własną warstwę. Malowanie może wtedy odbywać się na poziomie poszczególnych warstw, co jest kluczową optymalizacją dla ostatniego kroku.
Krok 5: Kompozycja - składanie ostatecznego obrazu
Ostatnim etapem jest Kompozycja. Przeglądarka bierze wszystkie indywidualnie namalowane warstwy i składa je w odpowiedniej kolejności, aby stworzyć ostateczny obraz wyświetlany na ekranie. To tutaj ujawnia się moc warstw.
Jeśli animujesz element, który znajduje się na własnej warstwie (na przykład używając transform: translateX(10px);
), przeglądarka nie musi ponownie uruchamiać etapów Układu ani Malowania dla całej strony. Może po prostu przesunąć istniejącą, namalowaną warstwę. Ta praca jest często przenoszona na procesor graficzny (GPU), co czyni ją niezwykle szybką i wydajną. To jest sekret płynnych animacji działających w 60 klatkach na sekundę (fps).
Wielkie wejście JavaScriptu: silnik interaktywności
Gdzie więc JavaScript wpasowuje się w ten uporządkowany potok? Wszędzie. JavaScript to dynamiczna siła, która może modyfikować DOM i CSSOM w dowolnym momencie po ich utworzeniu. To jest jego podstawowa funkcja i największe ryzyko dla wydajności.
Domyślnie JavaScript jest blokujący parser. Kiedy parser HTML napotyka tag <script>
(który nie jest oznaczony jako async
lub defer
), musi wstrzymać proces budowania DOM. Następnie pobierze skrypt (jeśli jest zewnętrzny), wykona go i dopiero wtedy wznowi parsowanie HTML. Jeśli ten skrypt znajduje się w sekcji <head>
dokumentu, może to znacznie opóźnić pierwsze renderowanie strony, ponieważ budowa DOM jest wstrzymana.
Blokować czy nie blokować: `async` i `defer`
Aby złagodzić to blokujące zachowanie, mamy dwa potężne atrybuty dla tagu <script>
:
defer
: Ten atrybut mówi przeglądarce, aby pobrała skrypt w tle, podczas gdy parsowanie HTML jest kontynuowane. Skrypt jest następnie gwarantowany do wykonania dopiero po zakończeniu pracy parsera HTML, ale przed wywołaniem zdarzeniaDOMContentLoaded
. Jeśli masz wiele odroczonych skryptów, zostaną one wykonane w kolejności, w jakiej pojawiają się w dokumencie. Jest to doskonały wybór dla skryptów, które potrzebują, aby pełny DOM był dostępny i których kolejność wykonania ma znaczenie.async
: Ten atrybut również mówi przeglądarce, aby pobrała skrypt w tle bez blokowania parsowania HTML. Jednakże, gdy tylko skrypt zostanie pobrany, parser HTML zostanie wstrzymany, a skrypt zostanie wykonany. Skrypty asynchroniczne nie mają gwarantowanej kolejności wykonania. Jest to odpowiednie dla niezależnych skryptów firm trzecich, takich jak analityka czy reklamy, gdzie kolejność wykonania nie ma znaczenia, a chcesz, aby uruchomiły się jak najszybciej.
Moc zmiany wszystkiego: manipulowanie DOM i CSSOM
Po wykonaniu, JavaScript ma pełny dostęp przez API zarówno do DOM, jak i CSSOM. Może dodawać elementy, usuwać je, zmieniać ich treść i modyfikować ich style. Na przykład:
document.getElementById('welcome-banner').style.display = 'none';
Ta pojedyncza linia JavaScriptu modyfikuje CSSOM dla elementu 'welcome-banner'. Ta zmiana unieważni istniejące Drzewo renderowania, zmuszając przeglądarkę do ponownego uruchomienia części potoku renderowania, aby odzwierciedlić aktualizację na ekranie.
Winowajcy wydajności: jak JavaScript zatyka potok
Za każdym razem, gdy JavaScript modyfikuje DOM lub CSSOM, istnieje ryzyko wywołania reflow i repaint. Chociaż jest to niezbędne dla dynamicznej sieci, nieefektywne wykonywanie tych operacji może doprowadzić aplikację do paraliżu. Przyjrzyjmy się najczęstszym pułapkom wydajnościowym.
Błędne koło: wymuszanie synchronicznych układów i „młócenie” układu (Layout Thrashing)
Jest to prawdopodobnie jeden z najpoważniejszych i najsubtelniejszych problemów z wydajnością w rozwoju front-endu. Jak już omówiliśmy, Układ jest kosztowną operacją. Aby być wydajnymi, przeglądarki są inteligentne i próbują grupować zmiany w DOM. Kolejkują twoje zmiany stylów w JavaScript, a następnie, w późniejszym momencie (zazwyczaj pod koniec bieżącej klatki), wykonają jedno obliczenie Układu, aby zastosować wszystkie zmiany naraz.
Możesz jednak zepsuć tę optymalizację. Jeśli twój JavaScript modyfikuje styl, a następnie natychmiast żąda wartości geometrycznej (takiej jak offsetHeight
, offsetWidth
lub getBoundingClientRect()
elementu), zmuszasz przeglądarkę do wykonania kroku Układu synchronicznie. Przeglądarka musi się zatrzymać, zastosować wszystkie oczekujące zmiany stylów, uruchomić pełne obliczenie Układu, a następnie zwrócić żądaną wartość do twojego skryptu. Nazywa się to wymuszonym synchronicznym układem.
Gdy dzieje się to w pętli, prowadzi do katastrofalnego problemu z wydajnością znanego jako „młócenie” układu (Layout Thrashing). Wielokrotnie odczytujesz i zapisujesz, zmuszając przeglądarkę do ponownego przeliczania układu całej strony w kółko w ramach jednej klatki.
Przykład „młócenia” układu (czego NIE robić):
function resizeAllParagraphs() {
const paragraphs = document.querySelectorAll('p');
for (let i = 0; i < paragraphs.length; i++) {
// READ: gets the width of the container (forces layout)
const containerWidth = document.body.offsetWidth;
// WRITE: sets the paragraph's width (invalidates layout)
paragraphs[i].style.width = (containerWidth / 2) + 'px';
}
}
W tym kodzie, wewnątrz każdej iteracji pętli, odczytujemy offsetWidth
(odczyt wyzwalający układ) i następnie natychmiast zapisujemy do style.width
(zapis unieważniający układ). To wymusza reflow dla każdego pojedynczego akapitu.
Wersja zoptymalizowana (grupowanie odczytów i zapisów):
function resizeAllParagraphsOptimized() {
const paragraphs = document.querySelectorAll('p');
// First, READ all the values you need
const containerWidth = document.body.offsetWidth;
// Then, WRITE all the changes
for (let i = 0; i < paragraphs.length; i++) {
paragraphs[i].style.width = (containerWidth / 2) + 'px';
}
}
Poprzez prostą restrukturyzację kodu, aby najpierw wykonać wszystkie odczyty, a następnie wszystkie zapisy, pozwalamy przeglądarce grupować operacje. Wykonuje ona jedno obliczenie Układu, aby uzyskać początkową szerokość, a następnie przetwarza wszystkie aktualizacje stylów, co prowadzi do jednego reflow na koniec klatki. Różnica w wydajności może być dramatyczna.
Blokada głównego wątku: długo działające zadania JavaScript
Główny wątek przeglądarki to pracowite miejsce. Jest odpowiedzialny za wykonywanie JavaScriptu, odpowiadanie na działania użytkownika (kliknięcia, przewijanie) i uruchamianie potoku renderowania. Ponieważ JavaScript jest jednowątkowy, jeśli uruchomisz złożony, długo działający skrypt, skutecznie blokujesz główny wątek. Kiedy twój skrypt działa, przeglądarka nie może robić nic innego. Nie może odpowiadać na kliknięcia, nie może przetwarzać przewijania i nie może uruchamiać żadnych animacji. Strona staje się całkowicie zamrożona i niereaktywna.
Każde zadanie, które trwa dłużej niż 50ms, jest uważane za 'Długie zadanie' i może negatywnie wpłynąć na doświadczenie użytkownika, w szczególności na wskaźnik Interaction to Next Paint (INP) Core Web Vital. Typowi winowajcy to złożone przetwarzanie danych, obsługa dużych odpowiedzi API lub intensywne obliczenia.
Rozwiązaniem jest dzielenie długich zadań na mniejsze części i 'oddawanie kontroli' głównemu wątkowi pomiędzy nimi. Daje to przeglądarce szansę na obsłużenie innych oczekujących prac. Prostym sposobem na to jest użycie setTimeout(callback, 0)
, które planuje wykonanie funkcji zwrotnej w przyszłym zadaniu, po tym jak przeglądarka będzie miała szansę odetchnąć.
Śmierć od tysiąca cięć: nadmierne manipulacje DOM
Chociaż pojedyncza manipulacja DOM jest szybka, wykonanie tysięcy z nich może być bardzo powolne. Za każdym razem, gdy dodajesz, usuwasz lub modyfikujesz element w żywym DOM, ryzykujesz wywołanie reflow i repaint. Jeśli musisz wygenerować dużą listę elementów i dołączać je do strony jeden po drugim, tworzysz wiele niepotrzebnej pracy dla przeglądarki.
Znacznie wydajniejszym podejściem jest budowanie struktury DOM 'offline' i następnie dołączenie jej do żywego DOM w jednej operacji. DocumentFragment
to lekki, minimalny obiekt DOM bez rodzica. Możesz myśleć o nim jak o tymczasowym kontenerze. Możesz dołączyć wszystkie swoje nowe elementy do fragmentu, a następnie dołączyć cały fragment do DOM za jednym razem. Skutkuje to tylko jednym reflow/repaint, niezależnie od liczby dodanych elementów.
Przykład użycia DocumentFragment:
const list = document.getElementById('my-list');
const data = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry'];
// Create a DocumentFragment
const fragment = document.createDocumentFragment();
data.forEach(itemText => {
const li = document.createElement('li');
li.textContent = itemText;
// Append to the fragment, not the live DOM
fragment.appendChild(li);
});
// Append the entire fragment in one operation
list.appendChild(fragment);
Szarpane ruchy: nieefektywne animacje JavaScript
Tworzenie animacji za pomocą JavaScriptu jest powszechne, ale robienie tego nieefektywnie prowadzi do zacinania się i 'jank'. Powszechnym antywzorcem jest używanie setTimeout
lub setInterval
do aktualizowania stylów elementów w pętli.
Problem polega na tym, że te timery nie są zsynchronizowane z cyklem renderowania przeglądarki. Twój skrypt może uruchomić się i zaktualizować styl tuż po tym, jak przeglądarka zakończyła malowanie klatki, zmuszając ją do dodatkowej pracy i potencjalnie przegapienia terminu następnej klatki, co skutkuje jej utratą.
Nowoczesnym, poprawnym sposobem na wykonywanie animacji w JavaScript jest użycie requestAnimationFrame(callback)
. To API informuje przeglądarkę, że chcesz wykonać animację i prosi, aby przeglądarka zaplanowała przemalowanie okna na następną klatkę animacji. Twoja funkcja zwrotna zostanie wykonana tuż przed tym, jak przeglądarka wykona kolejne malowanie, zapewniając, że twoje aktualizacje są idealnie zsynchronizowane i wydajne. Przeglądarka może również zoptymalizować działanie, nie uruchamiając funkcji zwrotnej, jeśli strona jest w tle.
Co więcej, co animujesz jest równie ważne jak jak to robisz. Zmiana właściwości takich jak width
, height
, top
, czy left
wywoła etap Układu, który jest powolny. Dla najpłynniejszych animacji, powinieneś trzymać się właściwości, które mogą być obsługiwane przez sam Kompozytor, który zazwyczaj działa na GPU. Są to głównie:
transform
(do przesuwania, skalowania, obracania)opacity
(do płynnego pojawiania się/znikania)
Animowanie tych właściwości pozwala przeglądarce po prostu przesuwać lub zmieniać przezroczystość istniejącej, namalowanej warstwy elementu bez potrzeby ponownego uruchamiania Układu lub Malowania. To jest klucz do osiągnięcia spójnych animacji 60fps.
Od teorii do praktyki: zestaw narzędzi do optymalizacji wydajności
Zrozumienie teorii to pierwszy krok. Teraz spójrzmy na kilka praktycznych strategii i narzędzi, których możesz użyć, aby przełożyć tę wiedzę na praktykę.
Inteligentne ładowanie skryptów
Sposób ładowania JavaScriptu to pierwsza linia obrony. Zawsze zadawaj sobie pytanie, czy skrypt jest naprawdę kluczowy dla początkowego renderowania. Jeśli nie, użyj defer
dla skryptów, które potrzebują DOM, lub async
dla niezależnych. W nowoczesnych aplikacjach stosuj techniki takie jak dzielenie kodu (code-splitting) za pomocą dynamicznego import()
, aby ładować tylko ten JavaScript, który jest potrzebny dla bieżącego widoku lub interakcji użytkownika. Narzędzia takie jak Webpack czy Rollup oferują również tree-shaking, aby eliminować nieużywany kod z twoich końcowych paczek, zmniejszając rozmiary plików.
Opanowanie zdarzeń o wysokiej częstotliwości: Debouncing i Throttling
Niektóre zdarzenia przeglądarki, takie jak scroll
, resize
i mousemove
, mogą być wywoływane setki razy na sekundę. Jeśli masz do nich podpiętą kosztowną obsługę zdarzeń (np. taką, która wykonuje manipulacje DOM), możesz łatwo zapchać główny wątek. Dwa wzorce są tutaj niezbędne:
- Throttling: Zapewnia, że twoja funkcja jest wykonywana co najwyżej raz na określony okres. Na przykład, 'uruchom tę funkcję nie częściej niż raz na 200ms'. Jest to przydatne w przypadku obsługi nieskończonego przewijania.
- Debouncing: Zapewnia, że twoja funkcja jest wykonywana dopiero po okresie bezczynności. Na przykład, 'uruchom tę funkcję wyszukiwania dopiero, gdy użytkownik przestanie pisać przez 300ms'. Jest to idealne dla pasków wyszukiwania z autouzupełnianiem.
Przenoszenie obciążenia: wprowadzenie do Web Workers
Dla naprawdę ciężkich, długo działających obliczeń JavaScript, które nie wymagają bezpośredniego dostępu do DOM, Web Workers są rewolucją. Web Worker pozwala uruchomić skrypt na oddzielnym wątku w tle. To całkowicie uwalnia główny wątek, aby mógł pozostać responsywny na działania użytkownika. Możesz przekazywać wiadomości między głównym wątkiem a wątkiem workera, aby wysyłać dane i otrzymywać wyniki. Przypadki użycia obejmują przetwarzanie obrazów, złożoną analizę danych lub pobieranie i buforowanie w tle.
Zostań detektywem wydajności: korzystanie z narzędzi deweloperskich przeglądarki
Nie możesz zoptymalizować czegoś, czego nie możesz zmierzyć. Panel Performance w nowoczesnych przeglądarkach, takich jak Chrome, Edge i Firefox, to twoje najpotężniejsze narzędzie. Oto krótki przewodnik:
- Otwórz Narzędzia deweloperskie (DevTools) i przejdź do zakładki 'Performance'.
- Kliknij przycisk nagrywania i wykonaj na swojej stronie działanie, które podejrzewasz o powolność (np. przewijanie, kliknięcie przycisku).
- Zatrzymaj nagrywanie.
Zostanie ci przedstawiony szczegółowy wykres płomieniowy (flame chart). Szukaj:
- Długie zadania (Long Tasks): Są one oznaczone czerwonym trójkątem. To są twoje blokery głównego wątku. Kliknij je, aby zobaczyć, która funkcja spowodowała opóźnienie.
- Fioletowe bloki 'Layout': Duży fioletowy blok wskazuje na znaczną ilość czasu spędzoną w etapie Układu.
- Ostrzeżenia o wymuszonym synchronicznym układzie: Narzędzie często jawnie ostrzega o wymuszonych reflow, pokazując dokładne linie kodu odpowiedzialne za to.
- Duże zielone bloki 'Paint': Mogą wskazywać na złożone operacje malowania, które można zoptymalizować.
Dodatkowo, zakładka 'Rendering' (często ukryta w szufladzie DevTools) ma opcje takie jak 'Paint Flashing', która podświetli obszary ekranu na zielono za każdym razem, gdy są przemalowywane. Jest to doskonały sposób na wizualne debugowanie niepotrzebnych przemalowań.
Podsumowanie: budowanie szybszej sieci, klatka po klatce
Potok renderowania przeglądarki to złożony, ale logiczny proces. Jako deweloperzy, nasz kod JavaScript jest stałym gościem w tym potoku, a jego zachowanie decyduje, czy pomaga stworzyć płynne doświadczenie, czy powoduje zakłócające wąskie gardła. Rozumiejąc każdy etap—od Parsowania do Kompozycji—zyskujemy wgląd potrzebny do pisania kodu, który pracuje z przeglądarką, nie przeciwko niej.
Kluczowe wnioski to połączenie świadomości i działania:
- Szanuj główny wątek: Utrzymuj go wolnym, odraczając niekrytyczne skrypty, dzieląc długie zadania i przenosząc ciężką pracę do Web Workers.
- Unikaj „młócenia” układu (Layout Thrashing): Strukturuj swój kod tak, aby grupować odczyty i zapisy DOM. Ta prosta zmiana może przynieść ogromne korzyści wydajnościowe.
- Bądź mądry z DOM: Używaj technik takich jak DocumentFragments, aby zminimalizować liczbę razy, gdy dotykasz żywego DOM.
- Animuj wydajnie: Preferuj
requestAnimationFrame
zamiast starszych metod opartych na timerach i trzymaj się właściwości przyjaznych dla kompozytora, takich jaktransform
iopacity
. - Zawsze mierz: Używaj narzędzi deweloperskich przeglądarki do profilowania swojej aplikacji, identyfikowania rzeczywistych wąskich gardeł i weryfikowania optymalizacji.
Budowanie wysokowydajnych aplikacji internetowych nie polega na przedwczesnej optymalizacji czy zapamiętywaniu niejasnych sztuczek. Chodzi o fundamentalne zrozumienie platformy, dla której tworzysz. Opanowując wzajemne oddziaływanie między JavaScriptem a potokiem renderowania, dajesz sobie możliwość tworzenia szybszych, bardziej odpornych i ostatecznie przyjemniejszych doświadczeń internetowych dla wszystkich i wszędzie.