jQuery lub javascript, aby znaleźć wykorzystanie pamięci strony

98

Czy istnieje sposób, aby dowiedzieć się, ile pamięci zajmuje strona internetowa lub moja aplikacja jquery?

Oto moja sytuacja:

Buduję aplikację internetową z dużą ilością danych, używając frontendu jquery i spokojnego zaplecza, które obsługuje dane w formacie JSON. Strona jest ładowana raz, a potem wszystko dzieje się przez ajax.

Interfejs użytkownika umożliwia użytkownikom tworzenie wielu kart w interfejsie użytkownika, a każda karta może zawierać mnóstwo danych. Zastanawiam się nad ograniczeniem liczby kart, które mogą utworzyć, ale pomyślałem, że fajnie byłoby ograniczyć je tylko wtedy, gdy użycie pamięci przekroczy określony próg.

W oparciu o odpowiedzi chciałbym uściślić:

  • Szukam rozwiązania uruchomieniowego (nie tylko narzędzi programistycznych), aby moja aplikacja mogła określać działania na podstawie wykorzystania pamięci w przeglądarce użytkownika.
  • Zliczanie elementów DOM lub rozmiaru dokumentu może być dobrym oszacowaniem, ale może być dość niedokładne, ponieważ nie zawierałoby powiązania zdarzeń, danych (), wtyczek i innych struktur danych w pamięci.
Tauren
źródło
Należy zbadać typ użytkowników aplikacji internetowej, aby określić, czy mają, czy nie mają problemów z pamięcią podczas korzystania z aplikacji internetowej. A może sam masz problemy z pamięcią / wydajnością w swojej aplikacji internetowej?
Prutswonder
@Prutswonder: Nie, nie mam problemów, ale byłem po prostu ciekawy, czy takie narzędzie istnieje. Pomyślałem, że zamiast ustawiania stałego limitu na kartach, dynamiczna metoda może być fajna.
Tauren
Właśnie dodałem kilka dodatkowych szczegółów do pytania, aby wyjaśnić, że szukam rozwiązania wykonawczego, a nie rozwiązania do kompilacji.
Tauren
2
Tylko pytanie, czy jeśli coś było już w pamięci podręcznej, czy to się liczy?
Ajax333221

Odpowiedzi:

65

Aktualizacja 2015

W 2012 roku nie było to możliwe, jeśli chciałeś obsługiwać wszystkie główne używane przeglądarki. Niestety, w tej chwili jest to nadal funkcja dostępna tylko w przeglądarce Chrome (niestandardowe rozszerzenie window.performance).

window.performance.memory

Obsługa przeglądarek: Chrome 6+


Odpowiedź z 2012 roku

Czy istnieje sposób, aby dowiedzieć się, ile pamięci zajmuje strona internetowa lub moja aplikacja jquery? Szukam rozwiązania uruchomieniowego (nie tylko narzędzi programistycznych), aby moja aplikacja mogła określać działania na podstawie wykorzystania pamięci w przeglądarce użytkownika.

Prosta, ale poprawna odpowiedź brzmi: nie . Nie wszystkie przeglądarki udostępniają Ci takie dane. I myślę, że powinieneś porzucić ten pomysł tylko z powodu złożoności i niedokładności a „wykonanego ręcznie” może wprowadzić więcej problemów niż je rozwiązać.

Zliczanie elementów DOM lub rozmiaru dokumentu może być dobrym oszacowaniem, ale może być dość niedokładne, ponieważ nie zawierałoby powiązania zdarzeń, danych (), wtyczek i innych struktur danych w pamięci.

Jeśli naprawdę chcesz trzymać się swojego pomysłu, powinieneś oddzielić stałą i dynamiczną zawartość.

Naprawiona treść nie jest zależna od działań użytkownika (pamięć używana przez pliki skryptów, wtyczki itp.)
Wszystko inne jest uważane za dynamiczne i powinno być głównym celem podczas określania limitu.

Nie ma jednak łatwego sposobu ich podsumowania. Możesz zaimplementować śledzenie system , który zbiera wszystkie te informacje. Wszystkie operacje powinny wywoływać odpowiednie metody śledzenia. na przykład:

Zawijaj lub nadpisz jQuery.datametodę informowania o śledzeniu systemu o alokacji danych.

Zawijaj manipulacje HTML, aby śledzić również dodawanie lub usuwanie treści ( innerHTML.lengthjest to najlepsze oszacowanie).

Jeśli przechowujesz duże obiekty w pamięci, powinny one również być monitorowane.

Jeśli chodzi o wiązanie zdarzeń, należy użyć delegowania zdarzeń, a wtedy można to również uznać za nieco ustalony czynnik.

Innym aspektem, który utrudnia prawidłowe oszacowanie wymagań dotyczących pamięci, jest to, że różne przeglądarki mogą alokować pamięć w różny sposób (dla obiektów JavaScript i elementów DOM).

gblazex
źródło
Czy innerHTML.lengthprzetwarzanie również nie wymaga pamięci, pamięci RAM lub procesora (lub czegokolwiek innego, nie mam pojęcia)?
mrReiha
Przeglądarka obsługuje tę funkcję NIE IE9 + ani nic poza Chrome. Window.performance.memory to tylko Chrome. docs.webplatform.org/wiki/apis/timing/properties/memory
Blunderfest,
Masz rację, myślałem, że pamięć była częścią standardu nawigacji i window.performanceprzedmiotu. Do tego standardu miały zastosowanie stare pozycje „obsługiwane przez”. window.performance.memoryjest uważany za niestandardowe rozszerzenie przeglądarki Chrome.
gblazex,
Aby włączyć monitorowanie pamięci w czasie rzeczywistym za pośrednictwem window.performance.memory, musisz uruchomić Chrome z flagą --enable-exact-memory-info.
kluverua
Aktualizacja: Opera również to obsługuje. Źródło: Mozilla. developer.mozilla.org/en-US/docs/Web/API/…
HoldOffHunger
39

Możesz użyć interfejsu Navigation Timing API .

Navigation Timing to interfejs API JavaScript do dokładnego pomiaru wydajności w sieci. Interfejs API zapewnia prosty sposób uzyskiwania dokładnych i szczegółowych statystyk dotyczących czasu - natywnie - dla nawigacji po stronach i zdarzeń ładowania.

window.performance.memory daje dostęp do danych o wykorzystaniu pamięci JavaScript.


Rekomendowane lektury

Sindre Sorhus
źródło
Świetna sugestia. Dziękuję Ci.
MaximOrlovsky
21

To pytanie ma już 5 lat, a javascript i przeglądarki bardzo się rozwinęły w tym czasie. Ponieważ jest to teraz możliwe (przynajmniej w niektórych przeglądarkach), a to pytanie jest pierwszym wynikiem wyszukiwania w Google „javascript show use memory”, pomyślałem, że zaoferuję nowoczesne rozwiązanie.

memory-stats.js: https://github.com/paulirish/memory-stats.js/tree/master

Ten skrypt (który możesz uruchomić w dowolnym momencie na dowolnej stronie) wyświetli bieżące wykorzystanie pamięci strony:

var script=document.createElement('script');
script.src='https://rawgit.com/paulirish/memory-stats.js/master/bookmarklet.js';
document.head.appendChild(script);

Dustin Brownell
źródło
1
Wygląda na to, że raportowane jest użycie pamięci JS, a nie wykorzystanie pamięci strony, wbudowany Menedżer zadań Chrome mówi, że Gmail używa 250 MB, podczas gdy memory-stats.js raportuje 33,7 MB
Brandito
Nie ma licencji na stronę github bookmarklet.js, więc przypuszczalnie jest to własność intelektualna chroniona prawem autorskim. To pozostawia pewien stopień niepewności w zależności od tego projektu.
HoldOffHunger
8

Nie znam żadnego sposobu, w jaki mógłbyś faktycznie dowiedzieć się, ile pamięci jest używane przez przeglądarkę, ale możesz być w stanie użyć heurystyki opartej na liczbie elementów na stronie. Uinsg jQuery, możesz to zrobić, $('*').lengtha to da ci liczbę elementów DOM. Szczerze mówiąc, prawdopodobnie łatwiej jest po prostu przeprowadzić testy użyteczności i wymyślić stałą liczbę kart do obsługi.

tvanfosson
źródło
3
@tvanfosson: niezły pomysł, ale to nie da mi informacji o pamięci innej niż DOM, takiej jak .data () i strukturach danych pamięci. Ale może to dać dobre oszacowanie całkowitej wagi, której mógłbym użyć.
Tauren
4

Użyj narzędzia Chrome Heap Snapshot

Istnieje również narzędzie Firebug o nazwie MemoryBug, ale wydaje się, że nie jest jeszcze bardzo dojrzałe.

Pablo Fernandez
źródło
@Pablo: Dzięki. Z pewnością będę korzystał z narzędzi deweloperskich, ale miałem nadzieję znaleźć coś, czego mógłbym użyć w czasie wykonywania, aby znaleźć użycie pamięci w przeglądarce każdego użytkownika.
Tauren
3

Jeśli chcesz zobaczyć tylko do testowania, istnieje sposób w Chrome za pośrednictwem strony programisty, aby śledzić użycie pamięci, ale nie wiesz, jak to zrobić bezpośrednio w javascript.

Zachary K
źródło
@Zachary: Dzięki. Z pewnością będę korzystał z narzędzi deweloperskich, ale miałem nadzieję znaleźć rozwiązanie do analizy środowiska uruchomieniowego.
Tauren
1
Jeśli znajdziesz jeden, daj mi znać, chciałbym mieć jedną pod ręką
Zachary K
3

Chciałbym zasugerować zupełnie inne rozwiązanie niż inne odpowiedzi, a mianowicie obserwować szybkość aplikacji, a gdy spadnie poniżej zdefiniowanych poziomów, albo pokaż użytkownikowi wskazówki dotyczące zamykania kart, albo wyłącz otwieranie nowych kart. Prostą klasą, która dostarcza tego rodzaju informacji, jest na przykład https://github.com/mrdoob/stats.js . Poza tym może nie być rozsądne, aby tak intensywna aplikacja przechowywała wszystkie karty w pamięci. Np. Utrzymywanie tylko stanu użytkownika (przewijanie) i ładowanie wszystkich danych za każdym razem, gdy otwierają się wszystkie oprócz dwóch ostatnich zakładek, może być bezpieczniejszą opcją.

Wreszcie, programiści webkitów dyskutowali o dodaniu informacji o pamięci do javascript, ale dostali wiele argumentów na temat tego, co, a czego nie powinno być ujawniane. Tak czy inaczej, nie jest nieprawdopodobne, że tego rodzaju informacje będą dostępne za kilka lat (chociaż nie są one obecnie zbyt przydatne).

David Mulder
źródło
1

Idealny czas na pytanie, kiedy zaczynam od podobnego projektu!

Nie ma dokładnego sposobu monitorowania wykorzystania pamięci JS w aplikacji, ponieważ wymagałoby to uprawnień wyższego poziomu. Jak wspomniano w komentarzach, sprawdzanie liczby wszystkich elementów itp. Byłoby stratą czasu, ponieważ ignoruje związane zdarzenia itp.

Byłby to problem z architekturą, gdyby wycieki pamięci były widoczne lub nieużywane elementy utrzymywały się. Dopilnowanie, aby zawartość zamkniętych zakładek została całkowicie usunięta bez pokutujących procedur obsługi zdarzeń itp. Byłoby idealne; zakładając, że to zrobione, możesz po prostu zasymulować intensywne użycie w przeglądarce i ekstrapolować wyniki z monitorowania pamięci (wpisz about: memory w pasku adresu)

Protip: jeśli otworzysz tę samą stronę w IE, FF, Safari ... i Chrome; a następnie przejdź do about: memory w Chrome, zgłosi użycie pamięci we wszystkich innych przeglądarkach. Schludny!

ov
źródło
0

Możesz chcieć, aby serwer śledził swoją przepustowość dla tej sesji (ile bajtów danych zostało do niego wysłanych). Gdy przekroczą limit, zamiast wysyłać dane przez ajax, serwer powinien wysłać kod błędu, którego użyje javascript, aby poinformować użytkownika, że ​​wykorzystał zbyt dużo danych.

Krzywka
źródło
@incrediman: to też fajny pomysł, ale nie sądzę, żeby zadziałał bez wbudowania wielu funkcji śledzenia - po prostu liczba bajtów nie zadziała. Problem polega na tym, że dane na karcie to lista, którą użytkownik będzie filtrować i sortować na wiele różnych sposobów. Za każdym razem, gdy wprowadzą zmiany, nowe dane będą pobierane z serwera i zastępują obecne elementy domeny. Co więcej, co powiesz, że nie klikną przycisku „odśwież” i nie zaczną od nowej strony? Musiałbym wtedy śledzić 304s i takie też, ale zamierzam po prostu obsługiwać statyczny html, wszystkie dane pochodzą z usługi REST.
Tauren
To podejście nie uwzględnia elementów utworzonych lub zniszczonych za pomocą funkcji createElement () lub remove (), co mogłoby wpłynąć na użycie pamięci klienta. Ale co ciekawe, różni się od innych odpowiedzi (mierząc po stronie serwera, a nie klienta, pomiary nie zmieniają pamięci, tak jak inne odpowiedzi).
HoldOffHunger
0

Możesz pobrać document.documentElement.innerHTML i sprawdzić jego długość. Dałoby ci to liczbę bajtów używanych przez twoją stronę internetową.

To może nie działać we wszystkich przeglądarkach. Możesz więc zawrzeć wszystkie elementy ciała w gigantycznym div i wywołać w nim innerhtml. Coś jak<body><div id="giantDiv">...</div></body>

Midhat
źródło
4
innerHTMLJest mało prawdopodobne, aby długość wygenerowanego ciągu znaków była użytecznie skorelowana z pamięcią używaną przez przeglądarkę (np. W jej wewnętrznym modelu obiektowym) do renderowania tego kodu HTML.
TJ Crowder
a czemu to? Moje uzasadnienie jest takie, że jeśli jakiś tekst zostanie załadowany do przeglądarki, musi zostać zapisany w pamięci. Więc daje pewną miarę pamięci używanej przez przeglądarkę do renderowania strony.
Midhat
4
Pomyśl o tym w ten sposób. Jeśli powiesz „Chciałbym dać Ci 10 milionów dolarów”, to 8 słów. Z drugiej strony, jeśli powiesz „Chciałbym kichnąć na twoją serwetkę”, to 7. Czy tylko pierwsze 8/7 jest cenniejsze niż drugie?
intuicyjny
1
Jest to podobne do sugestii @tvanfosson, aby uzyskać liczbę elementów DOM. Twój jest prawdopodobnie trochę dokładniejszy, ponieważ różne elementy dom mogą zawierać różne ilości tekstu. Ale nadal nie uzyskuje żadnych informacji o danych (), uchwytach kliknięć, strukturach danych i obiektach pamięci i tak dalej. Moja aplikacja korzysta z wielu z tych funkcji.
Tauren
1
W zakresie mogą znajdować się zmienne JS wskazujące na odłączone węzły DOM, które nie będą częścią elementu dokumentu. Możesz także napisać kod, który po prostu załaduje naprawdę długi ciąg do zmiennej, zużywając gigabajty pamięci, bez wpływu na tekst na stronie.
Josh Ribakoff