Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Wyciek pamięci (jQuery), jedna zakładka zajmuje 1GB pamięci w chrome
kamloo21
post 2.05.2013, 13:04:06
Post #1





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 8.07.2012

Ostrzeżenie: (0%)
-----


Hej
Mam problem z jquery , napisałem kilka animacji , wszystko ładnie działa lecz po pewnym czasie (jakieś 10min) drastycznie zwiększa się użycie pamięci które dochodzi do 1GB na 1 zakładke w Chrome.
Domyślam się że animacja jest źle zloopowana ale wydaję mi sie że jest OK. Próbowałem kilku różnych rzeczy

http://wytestuj.cba.pl/tyla/send.php Chodzi mi o tą animacje konkretnie (na reszcie strony jest inna więc nie zmieniajcie zakładki)

  1. $(document).ready(
  2. function animuj(){
  3. $("#loga").animate(
  4. { backgroundPosition: "+=2000" }, 19000 //animacja paska na dole
  5. ).animate(
  6. { backgroundPosition: "-=2000" }, 19000 //animacja paska na dole
  7. );
  8.  
  9. $("p.active").prev("p").css("border-bottom-color","#363732"); //zmiana koloru ramki nad .active
  10.  
  11. $("#menu p").hover( //animacja menu
  12. function(){
  13. $(this).prev().css("border-bottom-color","#363732");
  14. $(this).addClass("hover");
  15. },
  16. function(){
  17. if(!$(this).hasClass('active'))
  18. $(this).prev().css("border-bottom","#666 dotted 2px");
  19.  
  20. $(this).removeClass("hover");
  21. }
  22. );
  23.  
  24. setInterval(animuj,40000);
  25. }
  26. );
Go to the top of the page
+Quote Post
zegarek84
post 2.05.2013, 14:00:27
Post #2





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


po pewnym czasie masz wieeele razy odpaloną funkcję animuj i cyklicznie w postępie lawinowym podpinany setInterval(animuj,40000) - w tym miejscu co jest wystarczył by setTimeOut... lub troszkę inaczej to zapisać...

ps. nie potrzebnie wiele razy podpinasz .hover... prędzej byś skożystał z .delegate (coś jak .live)

ps2. skoro elementy #loga i #menu sa w drzewie DOM po .ready to mógłbyś te elementy wyszukać i zapamiętać w jakiejś zmiennej by ich nie szukać stale po selektorach CSS

ps3. jeśli elementy #menu nie zmieniają sie dynamicznie to wystarczyło by raz podpiąć .hover...

Ten post edytował zegarek84 2.05.2013, 14:01:37


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
kamloo21
post 2.05.2013, 15:50:42
Post #3





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 8.07.2012

Ostrzeżenie: (0%)
-----


Tzn .hover mam podpięte dokładnie 1 raz , chodzi ci o to żeby znajdował sie poza funkcją animuj , tak ?

Co do tych selektorów , to zapisać je przed .ready() czy w środku ? Bo wydaje mi się że mimo wszystko one i tak będą sie wyszukiwać na nowo

Zaraz spróbuję z tym setTimeOut i dam znać

Dzięki za nakierowanie smile.gif
Go to the top of the page
+Quote Post
zegarek84
post 2.05.2013, 16:32:06
Post #4





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


To co Ty napisałeś już poprawniej powinno działać przy takim zapisie (minimalna modyfikacja tylko więc HOVER będzie przypisywany dodatkowo przy każdej animacji - tu też będzie minimalny wyciek pamięci ale większość by go pominęła...)
[JAVASCRIPT] pobierz, plaintext
  1. $(document).ready(
  2. function(){
  3. function animuj(){
  4. $("#loga").animate(
  5. {
  6. backgroundPosition: "+=2000"
  7. }, 19000 //animacja paska na dole
  8. ).animate(
  9. {
  10. backgroundPosition: "-=2000"
  11. }, 19000 //animacja paska na dole
  12. );
  13.  
  14. $("p.active").prev("p").css("border-bottom-color","#363732"); //zmiana koloru ramki nad .active
  15.  
  16. $("#menu p").hover( //animacja menu
  17. function(){
  18. $(this).prev().css("border-bottom-color","#363732");
  19. $(this).addClass("hover");
  20. },
  21. function(){
  22. if(!$(this).hasClass('active'))
  23. $(this).prev().css("border-bottom","#666 dotted 2px");
  24.  
  25. $(this).removeClass("hover");
  26. }
  27. );
  28.  
  29. }
  30. setInterval(animuj,40000);
  31. animuj();
  32. }
  33. );
[JAVASCRIPT] pobierz, plaintext

skoro hover wystarczy raz przypisać więc dla zobrazowania z zapamiętanym elementem do animacji kod można by zapisać w ten sposób (urzyta tutaj 1 zmienna globalna - można to inaczej zapisać...)
[JAVASCRIPT] pobierz, plaintext
  1. var jLoga;
  2. function animuj(){
  3. jLoga.animate(
  4. {
  5. backgroundPosition: "+=2000"
  6. }, 19000 //animacja paska na dole
  7. ).animate(
  8. {
  9. backgroundPosition: "-=2000"
  10. }, 19000 //animacja paska na dole
  11. );
  12.  
  13. $("p.active").prev("p").css("border-bottom-color","#363732"); //zmiana koloru ramki nad .active
  14. }
  15. $(document).ready(
  16. function start(){
  17. jLoga = $("#loga");
  18. $("#menu p").hover( //animacja menu
  19. function(){
  20. $(this).prev().css("border-bottom-color","#363732");
  21. $(this).addClass("hover");
  22. },
  23. function(){
  24. if(!$(this).hasClass('active'))
  25. $(this).prev().css("border-bottom","#666 dotted 2px");
  26.  
  27. $(this).removeClass("hover");
  28. }
  29. );
  30. setInterval(animuj,40000);
  31. animuj();
  32. }
  33. );
[JAVASCRIPT] pobierz, plaintext

bez zmiennej globalnej można by np. w ten sposób - sposobów jest wiele i nie chcę narzucać rzadnego stylu, urzyta jest tutaj tylko dodatkowa anonimowa funkcja
[JAVASCRIPT] pobierz, plaintext
  1. $(document).ready(
  2. (function(){
  3. var jLoga;
  4. function animuj(){
  5. jLoga.animate(
  6. {
  7. backgroundPosition: "+=2000"
  8. }, 19000 //animacja paska na dole
  9. ).animate(
  10. {
  11. backgroundPosition: "-=2000"
  12. }, 19000 //animacja paska na dole
  13. );
  14.  
  15. $("p.active").prev("p").css("border-bottom-color","#363732"); //zmiana koloru ramki nad .active
  16. }
  17. function start(){
  18. jLoga = $("#loga");
  19. $("#menu p").hover( //animacja menu
  20. function(){
  21. $(this).prev().css("border-bottom-color","#363732");
  22. $(this).addClass("hover");
  23. },
  24. function(){
  25. if(!$(this).hasClass('active'))
  26. $(this).prev().css("border-bottom","#666 dotted 2px");
  27.  
  28. $(this).removeClass("hover");
  29. }
  30. );
  31. setInterval(animuj,40000);
  32. animuj();
  33. }
  34. return start;
  35. })()
  36. );
[JAVASCRIPT] pobierz, plaintext

w tamtym miejscu gdzie wcześniej miałeś setInterwal prędzej pasowała funkcja setTimeout...

ps.
nie wiem czy p.active zmienia się dynamicznie czy nie więc nie buforowałem tych selektorów... ale jeszcze jeśli gdzieś zmieniasz klasę .active to można by zbuforować jakiś element nadrzędny nie zmieniający się z jakimś np. id i w jQuery skożystać z kontekstów, więc nie szukać tych elementów p.active w całym dokumencie HTML tylko podać kontekst - ale to już takie zagadnienia optymalizacyjne...

Ten post edytował zegarek84 2.05.2013, 16:41:41


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
kamloo21
post 2.05.2013, 18:00:10
Post #5





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 8.07.2012

Ostrzeżenie: (0%)
-----


Poczytałem troche o setInterval i setTimeout i zastosowałem sie do twoich rad.
Sama zamiana z setInterval na setTimeout rozwiązała problem i teraz strona sie nie zawiesza i nie pobiera 1GB pamięci , lecz nadal bierze ~140MB co jest dużą liczbą
Myśle że drugie rozwiązanie które mi podesłałeś będzie OK, jak przerobie to napisze co i jak. Dzięki ! smile.gif


PS. W drugim rozwiązaniu jest var jLoga;
Czemu odrazu nie ustawiłeś wartości jLoga = $("#loga") ?

Ten post edytował kamloo21 2.05.2013, 18:02:51
Go to the top of the page
+Quote Post
zegarek84
post 2.05.2013, 21:37:59
Post #6





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


Cytat(kamloo21 @ 2.05.2013, 19:00:10 ) *
PS. W drugim rozwiązaniu jest var jLoga;
Czemu odrazu nie ustawiłeś wartości jLoga = $("#loga") ?

tylko to zależy, kiedy zaczyna się o tym myśleć ;p - a to dosyć ważne, gdyż jest to dostępne dopiero po documentready ;p, czyli jak cały DOM załadowany, po to z tej metody kożystałeś... ;p... trochę inaczej zapisane a to samo znaczące ;p - po prostu wcześniej tego elementu anie znajdziesz...
[JAVASCRIPT] pobierz, plaintext
  1. (function(){
  2. var jLoga;
  3. function animuj(){
  4. jLoga.animate(
  5. {
  6. backgroundPosition: "+=2000"
  7. }, 19000 //animacja paska na dole
  8. ).animate(
  9. {
  10. backgroundPosition: "-=2000"
  11. }, 19000 //animacja paska na dole
  12. );
  13.  
  14. $("p.active").prev("p").css("border-bottom-color","#363732"); //zmiana koloru ramki nad .active
  15. }
  16. function start(){
  17. jLoga = $("#loga");
  18. $("#menu p").hover( //animacja menu
  19. function(){
  20. $(this).prev().css("border-bottom-color","#363732");
  21. $(this).addClass("hover");
  22. },
  23. function(){
  24. if(!$(this).hasClass('active'))
  25. $(this).prev().css("border-bottom","#666 dotted 2px");
  26.  
  27. $(this).removeClass("hover");
  28. }
  29. );
  30. setInterval(animuj,40000);
  31. animuj();
  32. }
  33. $(document).ready(
  34. start
  35. );
  36. })();
[JAVASCRIPT] pobierz, plaintext



--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
PrinceOfPersia
post 2.05.2013, 23:03:26
Post #7





Grupa: Zarejestrowani
Postów: 717
Pomógł: 120
Dołączył: 18.04.2009

Ostrzeżenie: (0%)
-----


1. w Google Chrome jest profiler (z którego się dopiero uczę korzystać, w zasadzie dzięki temu wątkowi, zmotywowałem się i zacząłem się bawić (Ctrl + Shift + J, wybierz zakładkę Profiles, dalej "Take Heap Snapshot"). Może coś odkryjesz.

2. zainteresowałbym się animacjami CSS3 (@keyframes etc.) zamiast jQuery.animate (nie wiem czy to rozwiąże twój problem z pamięcią, bo problem może być gdzie indziej, ale spróbowac można)

Ten post edytował PrinceOfPersia 2.05.2013, 23:04:41


--------------------
Go to the top of the page
+Quote Post
zegarek84
post 3.05.2013, 09:09:31
Post #8





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


podejrzałem dzisiaj kod na Twojej stronie i widzę, że zrobiłeś "misz masz..." - zwróć uwagę, że nie buforujesz wyszukiwanych elementów choć je przypisujesz do zmiennej gdyż masz przypisane do zmiennej wewnątrz funkcji... masz teraz 2 funkcje animuj o.O - oczywiście wywoływana jest ta z bliższym scope...


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
kamloo21
post 3.05.2013, 11:24:14
Post #9





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 8.07.2012

Ostrzeżenie: (0%)
-----


Na strone wrzuciłem twoja wersje a moja wersja jest w komentarzu , wczoraj potestowałem to wszystko i teraz pobór pamięci utrzymuje się w granicach 26MB nawet po kilku godzinach więc udało się smile.gif Dzięki.
Jeszcze troche popracuje nad tym i będzie miodzio

@edit

W Chromie jest lepsza opcja , jak wejdziesz w Timeline kliknij na dole Record i masz cały wykres zużycia pamięci , FPSów itd

Ten post edytował kamloo21 3.05.2013, 11:51:16
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 18.04.2024 - 03:50