Ekstremalne JavaScript optymalizacja


Original: http://calendar.perfplanet.com/2009/extreme-javascript-optimization/

Jest dziwne zjawisko trwa w świecie JavaScript dziś. Choć język pozostał względnie niezmienione w ostatnim dziesięcioleciu, jest ewolucja afoot wśród programistów. Oni używają tego samego języka, który przyniósł nam stanu paska przewijania tekstu napisać całkiem Heavy Duty aplikacji client-side. Choć może to wydawać się wchodzimy na Lada w wyścigu F1, w rzeczywistości spędziliśmy ostatnie dziesięć lat jazdy bolidem F1 wyścig iz powrotem na podjeździe. Nigdy nie byliśmy za pomocą języka w jego pełnego potencjału. Zajęło odkrycie Ajax uruchomić nam z podjazdu i na torze wyścigowym. Ale teraz, że jesteśmy na drodze, jest dużo podkreślania i szlifowania narzędzi dzieje. Nie bardzo wiele osób wydaje się, wiedzieć, jak prowadzić bolid F1. Przynajmniej nie w 250 mph.

Rzecz w tym, że to całkiem łatwe do zakładania nogi na podłogę i uzyskać do 60 mph. Ale już wkrótce będziesz musiał zmieniać biegi, jeśli chcesz uniknąć szlifowania do zatrzymania. To samo z pisania dużych aplikacji client-side w JavaScript. Szybkie procesory dają nam wrażenie, że możemy zrobić wszystko i uciec z nim. A dla małych programów to prawda. Ale pisząc dużo złej JavaScriptu można bardzo szybko dostać się do sytuacji, w których kod zaczyna się czołgać. Więc tak jak przeciętny kierowca potrzebuje przeszkolenia do prowadzenia samochodu wyścigowego, musimy opanować tajniki tego języka, jeśli chcemy utrzymać go płynnie w dużych aplikacji skalę.

Zmienne

Rzućmy okiem na jeden z klamrami z programowaniem, variable.Some języki wymagają zadeklarować zmiennych przed ich użyciem, JavaScript nie. Ale tylko dlatego, że nie jest to konieczne, nie znaczy, że nie powinieneś tego robić. To dlatego, że w JavaScripcie czy zmienna nie jest jawnie zadeklarowane za pomocą słowa kluczowego “var”, to uważa się globalne i globalne są powolne. Dlaczego? Ponieważ interpreter musi dowiedzieć się, czy i gdzie zmienna ta została pierwotnie zadeklarowane, więc idzie wyszukiwanie. Weźmy następujący przykład.

Funkcja doSomething (val) {
liczyć + = val;
};

Czy liczba ma wartość przypisaną do niego poza zakresem doSomething? Czy jest to po prostu nie zostały zadeklarowane poprawnie? Również, w dużym programie, mając takie nazwy zmiennych globalnych generycznych utrudnia utrzymanie kolizji dzieje.

Pętle

Przeszukiwanie łańcuch zasięgu dla których liczba jest zadeklarowana w powyższym przykładzie nie taka wielka sprawa to jeśli zdarza się raz. Ale w dużych aplikacji internetowych, nie bardzo po prostu zdarza się raz. Zwłaszcza, gdy pętle są zainteresowane. Pierwszą rzeczą, aby pamiętać o pętli, a to nie jest po prostu dla JavaScriptu, jest do zrobienia, jak wiele pracy na zewnątrz pętli, jak to możliwe. Mniej zrobić w pętli, szybciej pętla będzie. Przy czym powiedział, rzućmy okiem na praktyce najczęściej w pętli JavaScriptu, których można uniknąć. Spójrz na poniższy przykład i zobaczyć, czy można na miejscu to:

for (var i = 0; i / / Jakiś kod tutaj
}

Widziałeś go? Długość tablicy arr jest przeliczany każdym razem pętla iteracje. Prosty fix jest to, aby buforować długość tablicy w taki sposób:

for (var i = 0, len arr.Length =; i / / Jakiś kod tutaj
}

W ten sposób, długość tablicy oblicza się tylko raz, i odnosi się do pętli buforowanej wartości przy każdym iteracje.

Co jeszcze możemy zrobić, aby poprawić wydajność naszej pętli? Cóż, co innego praca jest wykonywana na każdej iteracji? Cóż, mamy oceny, czy wartość i jest mniejsza niż wartość len i jesteśmy również zwiększenie i. o jeden. Możemy zmniejszyć liczbę operacji tutaj? Możemy jeśli zlecenie, w którym nasza pętla jest wykonywana, nie ma znaczenia.

for (var i = 100; i -;) {
/ / Jakiś kod tutaj
}

Ta pętla wykona 50% szybciej niż ten powyżej, ponieważ na każdej iteracji po prostu odejmuje wartość z I, a ponieważ wartość ta jest “falsy”, innymi słowy, to nie jest 0, to pętla długa. Chwila uderza wartość 0, pętla zatrzyma.

Możesz zrobić to z innymi rodzajami pętli, jak również:

while (i -) {
/ / Jakiś kod tutaj
}

Znowu, ponieważ ocena i działanie odjęcie 1 od I jest wykonane w tym samym czasie wszystkie potrzeby dla pętli podczas i być falsy lub 0, a pętla wyjść.

Buforowanie

Dotknąłem krótko na buforowanie powyżej kiedy buforowane długość tablicy w zmiennej. Sama zasada może być stosowane w wielu różnych miejscach w kodzie JavaScript. Zasadniczo to, co chcemy robić, aby uniknąć wysyłania interpreter się zrobić niepotrzebnej pracy raz to już zrobił to raz. Tak na przykład, jeśli chodzi o przeszukiwanie łańcucha zasięgu znaleźć zmienną globalną dla nas, buforowanie to odniesienie lokalnie uratuje tłumacza z pobierania za każdym razem. Pozwól, że ilustrują:

var aGlobalVar = 1;

Funkcja doSomething (val) {
var i = 1000, agv = aGlobalVar;
while (i -) {
agv + = val;
};
aGlobalVar = agv;
};

doSomething (10);

W tym przykładzie, tylko pobrane aGlobalVar razy, nie na tysiąc razy. Pobieramy go raz, aby uzyskać jej wartość, a następnie udajemy się do niego ponownie, aby ustawić nową wartość. Gdybyśmy używali go w pętli while, interpreter będzie już do pobrania z tej zmiennej tysiąc razy. W rzeczywistości, loop powyżej zajmuje około 3ms do uruchomienia w przypadku, gdy średnia + = val; zastąpiono aGlobalVar + = val; następnie pętla potrwa około 10ms do uruchomienia.

Głębokość Właściciel

Zagnieżdżanie obiektów w celu użycia notacji dot jest to świetny sposób na nazw i organizować swój kod. Unforutnately, jeśli chodzi o wydajność, to może być trochę problem. Za każdym razem wartość jest dostępna w tego typu sytuacji, tłumacz musi przechodzić przez obiekty masz zagnieżdżone aby dostać się do tej wartości. Głębsza wartość, tym bardziej traversal, dłużej czekać. Więc nawet przestrzeni nazw jest doskonałym narzędziem organizacyjnym, utrzymanie rzeczy jako płytkie, jak to możliwe jest najlepszy na przyspieszenie pracy. Najnowsze wcielenie biblioteki YUI rozwinęła się wyeliminować całą warstwę gniazd z jego przestrzeni nazw. Tak na przykład, YAHOO.util.Anim teraz Y.Anim.

Streszczenie

To tylko kilka przykładów, jak poprawić swój kod wydajność, zwracając uwagę na to, jak interpreter JavaScript wykonuje swoją pracę. Należy pamiętać jednak, że przeglądarki są stale ewoluuje, nawet jeśli język nie jest. Tak na przykład, dzisiejsze przeglądarki są wprowadzenie JIT kompilatory do przyspieszenia wydajności. Ale to nie znaczy, że powinniśmy być mniej czujna w naszych praktyk. Bo w końcu, gdy Twoja aplikacja internetowa jest ogromny sukces i świat patrzy, liczy się każda milisekunda.