Częste błędy JavaScript, które poważnie wpływają na wydajność? [Zamknięte]


10

Na niedawnym spotkaniu UI / UX, w którym uczestniczyłem, przekazałem informacje zwrotne na stronie internetowej, która używała Javascript (jQuery) do interakcji i interfejsu użytkownika - były to dość proste animacje i manipulacje, ale wydajność na przyzwoitym komputerze była przerażająca.

Przypomniało mi to wiele stron / programów, które widziałem z tym samym problemem, w których pewne działania po prostu absolutnie niszczą wydajność. Jest to głównie w (lub co najmniej bardziej zauważalne) sytuacjach, w których JavaScript prawie zastępuje Flash. Jest to wyraźny kontrast z niektórymi aplikacjami internetowymi, których używałem, które mają znacznie więcej Javascript i funkcjonalność, ale działają bardzo płynnie (COGNOS firmy IBM to taki, który mogę sobie wyobrazić z góry).

Chciałbym poznać niektóre z typowych problemów, które nie są brane pod uwagę przy opracowywaniu JS, które zabijają wydajność witryny.


Prawdopodobnie to samo, co w przypadku każdego innego programu: Wykonywanie więcej pracy niż to konieczne i wykonywanie tej samej pracy w kółko, często setki razy.

1
@ delnan to prawda, ale wygląda na to, że w JS jest znacznie bardziej rozpowszechniona. Może postrzeganie?
— Nic.

1
Mówiąc o JavaScripcie, mówienie o „witrynie” jest dość zwyczajne. Jest wszędzie i jest używany do wszystkiego we współczesnych czasach.
— Adam Crossland

@Adam Crossland masz całkowitą rację - myślę, że w tym samym przypadku pomogłem programistom z natywną aplikacją, która również w dużym stopniu polegała na jQuery.
— Nic.

1
Nie jest to dokładnie odpowiedź na twoje pytanie, więc robię z tego komentarz: napotkałem sytuacje, w których JavaScript generowało dużo renderowania, a tak naprawdę silnik renderowania przeglądarki zużył sekundy. Dlatego, aby poradzić sobie z wąskim gardłem wydajności, najpierw szukałbym niepotrzebnych operacji renderowania.
— user281377,

Odpowiedzi:


8

Typowy zabójca wydajności wywołuje .lengthfunkcję HTMLCollection w forpętli:

function foo(collection) {
    for (var index = 0; index < collection.length; index++) {
        // do something awesome here
    }
}

Ten anty-wzór powoduje, że wielkość kolekcji jest obliczana przy każdym przejściu przez pętlę. Lepszym rozwiązaniem jest obliczenie długości poza pętlą:

function foo(collection) {
    var collectionLen = collection.length;
    for (var index = 0; index < collectionLen; index++) {
        // do something awesome here
    }
}

3
Zależy od przeglądarki. Weź ten wzorzec jako przykład: w FF 5, „normalne” One działa w prawie tym samym czasie co „zoptymalizowane” wersji. I nawet w naprawdę starych i powolnych przeglądarkach, coś takiego prawdopodobnie nie będzie wąskim gardłem, jeśli JS rzeczywiście zrobi coś interesującego z elementami.

1
Hmm! Być może dzisiejsze wysoce optymalizujące kompilatory JIT sprawiają, że ta odrobina mądrości staje się przestarzała.
— Adam Crossland

4
Nie jestem tutaj prawdziwym ekspertem, ale ze specyfikacji ECMA wynika, że ​​długość jest tylko właściwością obiektu tablicy. Tak więc wywołanie go zwraca wartość zamiast zliczać wszystkie elementy. Nie mam pojęcia, czy wszystkie implementacje są zgodne ze specyfikacją, ale jeśli tak, kod w ogóle nie poprawia wydajności.
— Jacek Prucia

4
@JacekPrucia Powiedział, że kolekcja , a nie tablica - zwykle w prawdziwym kodzie oznacza to listę elementów DOM zwróconych przez funkcje takie jak document.getElementsByTagName. Funkcja zwraca aktywność, nodeListktóra ponownie oblicza jej długość za każdym razem, gdy .lengthuzyskuje się dostęp do właściwości.
— Yi Jiang

2
Test porównawczy @JacekPrucia to poprawa wydajności. Wyszukiwanie nieruchomości nie jest tanie.
— Raynos

4

Nie, problem nie pochodzi od JS używanego jako zamiennik pamięci flash. Jeśli nie jesteś do tego przekonany, udokumentuj informacje o skryptach akcji: jest bardzo zbliżony do JS.

Jako zabójca występów możesz znaleźć kilka złych praktyk:

  • Dołącz moduł obsługi zdarzeń do zdarzeń ciągłych, takich jak przewijanie, poruszanie myszką lub podobne rzeczy. Ma to dwie wady: jeśli zdarzenie nie zostanie wystarczająco uruchomione, aplikacja nie będzie reaktywna. Jeśli uruchomi się za bardzo, będziesz mieć ogromne obciążenie procesora za darmo.
  • Wykonywanie synchronicznych wywołań AJAX. JavaScript nie jest wielowątkowy, więc gdy część JS na coś czeka, aplikacja zostaje zawieszona. Lepiej użyj asynchronicznych wywołań AJAX i w ten sam sposób użyj setTimeout / setInterval, aby podzielić długą fazę obliczeń i zachować aktywność aplikacji.
  • Wysoka złożoność algorytmu jak w innych językach.

Widziałem więcej niż kilka aplikacji, które próbują obracać, ułatwiać lub animować obrazy w pełnej przeglądarce i nie udaje im się to w tym procesie - stąd pochodzi komentarz dotyczący wymiany Flasha :)
— Nic

Ponieważ pierwszy A w AJAX oznacza asynchroniczny, technicznie nie jest to AJAX, jeśli jest synchroniczny, ale twój punkt jest nadal dobry.
— Karl Bielefeldt,

Tak, prawda, to nie jest wyłącznie AJAX. Ale i tak należy tego unikać: D
— deadalnix

3

Dałem trochę opinii na stronie internetowej, która używała Javascript (jQuery) do interakcji i interfejsu użytkownika - były to dość proste animacje i manipulacje, ale wydajność na przyzwoitym komputerze była przerażająca.

Jednym z największych problemów z wydajnością jest używanie abstrakcyjnych poziomów wysokiego poziomu (takich jak jQuery) bez zrozumienia podstawowego modelu DOM i modelu animacji CSS3 (lub obszaru roboczego lub svg).

Jeśli nie wiesz, jak to zrobić bez abstrakcji, masz absolutną zerową wiedzę o tym, jakie techniki są szybkie lub wolne.

Ucz się JavaScript, ucz się DOM. Gdy poznasz tych dwóch i wiesz, co robią twoje abstrakcje, możesz je efektywnie wykorzystać. Oczywiście przez większość czasu zdajesz sobie sprawę, że abstrakcja jest wolna i po prostu rób to ręcznie bez biblioteki.


1

Zaletą i wadą Javascript jest to, że jest on niezwykle elastyczny. To powiedziawszy, w rzeczywistości pozwala ci robić rzeczy, których prawdopodobnie nie powinieneś robić w wielu przypadkach.

Z recenzji kodu, w których byłem częścią, główne obawy związane są z renderowaniem CSS. W przypadku nowszych programistów JS mamy tendencję do dostrzegania zbyt wielu zmiennych używanych w zasięgu globalnym.

Nieprawidłowe zamknięcia często powodują przeciek pamięci. Jednak większość współczesnych frameworków JavaScript zapobiega tego rodzaju problemom, o ile kod podąża za nimi.


0

Oto szybki link, który znalazłem rok temu o pisaniu lepszego kodu jquery: http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance /

Jedną rzeczą, którą właśnie znalazłem w kodzie współpracowników, który zabijał wydajność, było buforowanie danych, które nie musiały być buforowane.

Przykład:

var table = $("#data").dataTable(.....);

DataTables to wtyczka jQuery, której używamy do tworzenia ładnych siatek. W każdym razie w tabeli było prawie 5 tys. Wierszy, zastosowanie wtyczki DataTables, a następnie zapisanie jej w zmiennej tabeli faktycznie spowodowało, że zarówno FireFox, jak i IE ostrzegły, że skrypt trwa zbyt długo. Morał tej historii, buforuj dane tylko w razie potrzeby.


1
Wygląda na to, że DataTables to naprawdę nieefektywna / słaba wtyczka, a nie problem z buforowaniem. 5k to nic.
— Raynos

@Raynos: Powiedział 5 tysięcy wierszy , a nie 5 kilobajtów danych. „Rząd” może być bardzo dużą rzeczą.
— Chris Farmer

@ChrisFarmer Jeśli „wiersz” jest bardzo dużą rzeczą, masz inny problem.
— Raynos

-1

Z tego, co słyszałem, forpętle są obliczeniowo szybsze niż jQuery $.each().


3
Czy to żart?
— Raynos
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.