Dowiedz się, jak używać Chrome i Narzędzi deweloperskich do znajdowania problemów z pamięcią, które wpływają na wydajność strony, takich jak wycieki pamięci, nadmierne wykorzystanie pamięci i częste czyszczenie pamięci.
Podsumowanie
- Sprawdź, ile pamięci używa Twoja strona, korzystając z Menedżera zadań Chrome.
- Wizualizuj wykorzystanie pamięci w czasie za pomocą nagrań na osi czasu.
- Identyfikowanie odłączonych drzew DOM (częstej przyczyny wycieków pamięci) za pomocą zrzutów sterty.
- Dzięki nagraniom osi czasu alokacji dowiesz się, kiedy w stercie JS jest przydzielana nowa pamięć.
- identyfikować odłączone elementy przechowywane przez odwołanie JavaScriptu;
Przegląd
Zgodnie z modelem wydajności RAIL działania związane z wydajnością powinny koncentrować się na użytkownikach.
Problemy z pamięcią są ważne, ponieważ często są zauważalne dla użytkowników. Użytkownicy mogą zauważyć problemy z pamięcią w następujący sposób:
- Wydajność strony pogarsza się z upływem czasu. Może to być objaw wycieku pamięci. Wyciek pamięci występuje, gdy błąd na stronie powoduje, że z czasem zużywa ona coraz więcej pamięci.
- Wydajność strony jest stale niska. Może to być objawem przepełnienia pamięci. Przepełnienie pamięci występuje, gdy strona używa więcej pamięci, niż jest to konieczne do uzyskania optymalnej szybkości strony.
- Wydajność strony jest opóźniona lub często się zatrzymuje. Może to być objaw częstego czyszczenia pamięci. Odzyskiwanie pamięci to proces, w którym przeglądarka odzyskuje pamięć. Przeglądarka decyduje, kiedy to nastąpi. Podczas zbierania danych wykonywanie wszystkich skryptów jest wstrzymane. Jeśli więc przeglądarka często usuwa niepotrzebne dane, wykonywanie skryptu będzie często wstrzymywane.
Przepełnienie pamięci: ile to „za dużo”?
Wyciek pamięci można łatwo zdefiniować. Jeśli witryna stopniowo zużywa coraz więcej pamięci, oznacza to, że występuje wyciek. Jednak przepełnienie pamięci jest nieco trudniejsze do wykrycia. Co oznacza „używanie zbyt dużej ilości pamięci”?
Nie ma tu konkretnych liczb, ponieważ różne urządzenia i przeglądarki mają różne możliwości. Ta sama strona, która działa płynnie na smartfonie wysokiej klasy, może ulec awarii na smartfonie niższej klasy.
Kluczem jest użycie modelu RAIL i skupienie się na użytkownikach. Dowiedz się, jakie urządzenia są popularne wśród Twoich użytkowników, a następnie przetestuj na nich swoją stronę. Jeśli jakość jest stale niska, strona może przekraczać możliwości pamięci tych urządzeń.
monitorować wykorzystanie pamięci w czasie rzeczywistym za pomocą Menedżera zadań Chrome;
Zacznij od Menedżera zadań Chrome, aby zbadać problem z pamięcią. Menedżer zadań to monitor działający w czasie rzeczywistym, który pokazuje, ile pamięci używa strona.
Naciśnij Shift + Esc lub otwórz menu główne Chrome i wybierz Więcej narzędzi > Menedżer zadań, aby otworzyć Menedżera zadań.

Kliknij prawym przyciskiem nagłówek tabeli Menedżera zadań i włącz Pamięć JavaScript.

Te 2 kolumny zawierają różne informacje o tym, jak strona korzysta z pamięci:
- Kolumna Wykorzystanie pamięci reprezentuje pamięć systemu operacyjnego. Węzły DOM są przechowywane w pamięci systemu operacyjnego. Jeśli ta wartość rośnie, tworzone są węzły DOM.
Kolumna Pamięć JavaScript reprezentuje stertę JS. Ta kolumna zawiera 2 wartości. Wartość, która Cię interesuje, to liczba aktywnych (liczba w nawiasie). Liczba aktywnych obiektów pokazuje, ile pamięci używają obiekty osiągalne na stronie. Jeśli ta liczba rośnie, oznacza to, że tworzone są nowe obiekty lub istniejące obiekty się powiększają.

Wizualizacja wycieków pamięci za pomocą nagrań wydajności
Możesz też użyć panelu Wydajność jako innego punktu wyjścia do analizy. Panel Wydajność pomaga wizualizować wykorzystanie pamięci przez stronę na przestrzeni czasu.
- Otwórz panel Wydajność w Narzędziach deweloperskich.
- Zaznacz pole wyboru Pamięć.
- Utwórz nagranie.
Aby zademonstrować nagrania pamięci w panelu Wydajność, rozważ ten kod:
var x = [];
function grow() {
for (var i = 0; i < 10000; i++) {
document.body.appendChild(document.createElement('div'));
}
x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
Za każdym razem, gdy przycisk, do którego odwołuje się kod, zostanie naciśnięty, do treści dokumentu zostanie dołączonych 10 tysięcy węzłów div, a do tablicy x zostanie dodany ciąg znaków x o długości 1 miliona.
Uruchomienie tego kodu spowoduje utworzenie nagrania na osi czasu, takiego jak na tym zrzucie ekranu:

Najpierw wyjaśnimy, jak działa interfejs. Wykres HEAP w panelu Przegląd (poniżej NET) przedstawia stertę JS. Poniżej panelu Przegląd znajduje się panel Licznik. Możesz tu zobaczyć wykorzystanie pamięci podzielone na stertę JS (tak samo jak na wykresie HEAP w panelu Overview), dokumenty, węzły DOM, detektory i pamięć GPU. Odznaczenie pola wyboru powoduje ukrycie go na wykresie.
Teraz przeanalizuję kod i porównam go ze zrzutem ekranu. Jeśli spojrzysz na licznik węzłów (zielony wykres), zobaczysz, że jest on zgodny z kodem. Liczba węzłów zwiększa się w dyskretnych krokach. Możesz założyć, że każdy wzrost liczby węzłów jest wywołaniem funkcji grow(). Wykres sterty JS (niebieski wykres) nie jest tak prosty. Zgodnie ze sprawdzonymi metodami pierwszy spadek to wymuszone czyszczenie pamięci (osiągnięte przez naciśnięcie przycisku Wyczyść pamięć). W miarę postępu nagrywania widać, że rozmiar sterty JS gwałtownie rośnie. Jest to naturalne i oczekiwane: kod JavaScript tworzy węzły DOM przy każdym kliknięciu przycisku i wykonuje dużo pracy, gdy tworzy ciąg znaków o długości miliona znaków. Kluczowe jest to, że sterta JS kończy się wyżej niż się zaczęła („początek” to punkt po wymuszonym odśmiecaniu pamięci). W rzeczywistości, gdybyśmy zobaczyli taki wzorzec zwiększania rozmiaru sterty JS lub rozmiaru węzła, mogłoby to oznaczać wyciek pamięci.
Wykrywanie wycieków pamięci w odłączonym drzewie DOM za pomocą zrzutów sterty
Węzeł DOM może zostać usunięty przez mechanizm odzyskiwania pamięci tylko wtedy, gdy nie ma do niego odwołań w drzewie DOM strony ani w kodzie JavaScript. Węzeł jest „odłączony”, gdy zostanie usunięty z drzewa DOM, ale nadal odwołuje się do niego jakiś kod JavaScript. Odłączone węzły DOM są częstą przyczyną wycieków pamięci. W tej sekcji dowiesz się, jak używać programów profilujących sterty w Narzędziach deweloperskich do identyfikowania odłączonych węzłów.
Oto prosty przykład odłączonych węzłów DOM.
var detachedTree;
function create() {
var ul = document.createElement('ul');
for (var i = 0; i < 10; i++) {
var li = document.createElement('li');
ul.appendChild(li);
}
detachedTree = ul;
}
document.getElementById('create').addEventListener('click', create);
Kliknięcie przycisku, do którego odwołuje się kod, powoduje utworzenie węzła ul z 10 węzłami podrzędnymi li. Kod odwołuje się do tych węzłów, ale nie istnieją one w drzewie DOM, więc są odłączone.
Zrzuty sterty to jeden ze sposobów identyfikowania odłączonych węzłów. Jak sama nazwa wskazuje, zrzuty sterty pokazują, jak pamięć jest rozdzielana między obiekty JS i węzły DOM strony w momencie tworzenia zrzutu.
Aby utworzyć zrzut, otwórz Narzędzia deweloperskie i przejdź do panelu Pamięć, zaznacz opcję Zrzut sterty, a następnie kliknij przycisk Zrób zrzut.

Przetworzenie i wczytanie podsumowania może trochę potrwać. Po zakończeniu wybierz go w panelu po lewej stronie (o nazwie Zrzuty sterty).
Wpisz Detached w polu tekstowym Filtr klas, aby wyszukać odłączone drzewa DOM.

Rozwiń strzałki, aby zbadać odłączone drzewo.

Kliknij węzeł, aby go dokładniej zbadać. W panelu Obiekty możesz zobaczyć więcej informacji o kodzie, który się do niego odwołuje. Na przykład na zrzucie ekranu poniżej widać, że zmienna detachedTree odwołuje się do węzła. Aby naprawić ten konkretny wyciek pamięci, musisz przeanalizować kod, który używa elementu detachedTree, i upewnić się, że usuwa on odwołanie do węzła, gdy nie jest już potrzebny.

Identyfikowanie wycieków pamięci sterty JS za pomocą osi czasu alokacji
Oś czasu alokacji to kolejne narzędzie, które może pomóc w wykrywaniu wycieków pamięci w stercie JS.
Aby zademonstrować oś czasu alokacji, przeanalizujmy ten kod:
var x = [];
function grow() {
x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
Za każdym razem, gdy przycisk, do którego odwołuje się kod, zostanie naciśnięty, do tablicy x zostanie dodany ciąg znaków o długości 1 miliona znaków.
Aby zarejestrować oś czasu alokacji, otwórz Narzędzia deweloperskie, przejdź do panelu Pamięć, kliknij przycisk Alokacje na osi czasu, kliknij przycisk Nagraj, wykonaj działanie, które Twoim zdaniem powoduje wyciek pamięci, a gdy skończysz, kliknij przycisk Zatrzymaj nagrywanie.
Podczas nagrywania sprawdź, czy na osi czasu alokacji pojawiają się niebieskie paski, jak na zrzucie ekranu poniżej.

Te niebieskie paski reprezentują nowe alokacje pamięci. Te nowe alokacje pamięci są potencjalnymi wyciekami pamięci. Możesz powiększyć pasek, aby przefiltrować panel Konstruktor i wyświetlić tylko obiekty, które zostały przydzielone w określonym przedziale czasu.

Rozwiń obiekt i kliknij jego wartość, aby wyświetlić więcej informacji o nim w panelu Obiekt. Na przykład na zrzucie ekranu poniżej, wyświetlając szczegóły nowo przydzielonego obiektu, możesz zobaczyć, że został on przydzielony do zmiennej x w zakresie Window.

Sprawdzanie alokacji pamięci według funkcji
Aby wyświetlić alokację pamięci według funkcji JavaScriptu, użyj typu profilu Próbkowanie alokacji w panelu Pamięć.

- Kliknij opcję Próbkowanie przydziału. Jeśli na stronie jest skrypt, możesz go wybrać jako cel profilowania w oknie Wybierz wystąpienie maszyny wirtualnej JavaScript.
- Naciśnij przycisk Rozpocznij.
- Wykonaj na stronie działania, które chcesz zbadać.
- Po zakończeniu wszystkich działań naciśnij przycisk Zatrzymaj.
Narzędzia deweloperskie pokazują podział alokacji pamięci według funkcji. Domyślny widok to Heavy (Bottom Up) (Ciężkie (od dołu do góry)), który wyświetla funkcje, które przydzieliły najwięcej pamięci na górze.

Identyfikowanie obiektów przechowywanych przez odwołanie JS
Profil Odłączone elementy pokazuje odłączone elementy, które nadal istnieją, ponieważ odwołuje się do nich kod JavaScript.
Zarejestruj profil Odłączone elementy, aby wyświetlić dokładne węzły HTML i ich liczbę.

Wykrywanie częstego odśmiecania pamięci
Jeśli strona często się zatrzymuje, mogą występować problemy z odzyskiwaniem pamięci.
Aby wykryć częste operacje czyszczenia pamięci, możesz użyć Menedżera zadań Chrome lub nagrań pamięci na osi czasu. W Menedżerze zadań często rosnące i malejące wartości Pamięć lub Pamięć JavaScript oznaczają częste operacje czyszczenia pamięci. Na nagraniach osi czasu często rosnące i malejące wykresy sterty JS lub liczby węzłów wskazują na częste operacje czyszczenia pamięci.
Po zidentyfikowaniu problemu możesz użyć nagrania osi czasu alokacji, aby dowiedzieć się, gdzie jest przydzielana pamięć i które funkcje powodują alokacje.