Optymalizacja JavaScript

Najczęściej spotykanym zastosowaniem języka JavaScript są strony WWW. Wolne działanie napisanych przez nas skryptów może odstraszyć potencjalnych użytkowników. Powinniśmy się więc starać aby nasze aplikacje działały sprawnie i szybko. JavaScript jako język  interpretowalny jest nieporównywalnie wolniejsza od języków kompilowalnych, zazwyczaj jednak programy pisane w JS są na tyle małe aby nie dało się tego zauważyć. Problemy zaczynają się gdy nasz kod rozrasta się i zaczynamy spostrzegać niepokojące nas spowolnienie.

Jak temu zaradzić:

1. Narzędzia

Potrzebujemy odpowiednich narzędzi aby móc sprawdzić czy wprowadzane przez nas poprawki przynoszą jakiekolwiek efekty. Z pomocą może przyjść nam dodatek do Firefoxa Firebug, z pomocą którego będziemy mogli śledzić ewentualne błędy w naszym skrypcie oraz monitorować prędkość wykonywania wybranych fragmentów naszej aplikacji.

Czas wywołania fragmentów kodu możemy monitorować za pomocą konsoli:

console.time("naszaFunkcja");
naszaFunkcja();
console.timeEnd("naszaFunkcja") ;

Po odświeżeniu strony na której umieszczony jest ten kod, w konsoli Firebug’a powinniśmy zobaczyć powiadomienie:

Optymalizacja Javascript  - Firebug konsola

Wiemy więc już jak będziemy sprawdzać czy wprowadzane zmiany przynoszą efekt, możemy więc zacząć je wprowadzać.

2. Zamiana zmiennych globalnych na lokalne

Zamiast:

var glob = 2;
function fun(){
glob= glob * glob * glob;
}

Napisz:

var glob = 2;
function fun(){
var loc = glob;
loc = loc* loc* loc;
glob = loc;
}

Uzasadnienie: Dostęp do zmiennych lokalnych w JS jest znacznie szybszy niż do zmiennych globalnych ( więcej o scope chain). Działanie takie ma sens tylko jeżeli do zmiennej globalnej odwołujemy się w funkcji więcej niż raz.

3. Unikaj używania with

Uzasadnienie: Powoduje dodanie dodatkowych pól do scope chain, co znacząco wpływa na szybkość odwołań do zmiennych lokalnych i globalnych.

4. Pamiętaj o używaniu var podczas deklarowania zmiennych.

5. Dostęp do atrybutów obiektów

Pamiętaj o tym, że dostęp do atrybutu obiektu np. object.name zawsze będzie szybszy niż object.name.name . ( Nie ma natomiast różnicy pomiędzy odwołaniami object.name i object.[„name”]. )

Zamiast:

function fun( data ){
if( data.count > 0 ){
for( var i = 0 ; i< data.count ; i++){
fun_2( data.item[i] );
}
}
}

Napisz:

function fun( data ){
var  count = data.count ,   item = data.item ;

if( count > 0 ){

for( var i = 0 ; i< count ; i++){
fun_2( item[i] );
}
}
}

6. Pętle

Nie istotne jest, którego rodzaju pętli używasz ( while, for, do-while ) najważniejsze jest jakie zabiegi przeprowadzasz wewnątrz pętli oraz ilość iteracji jakie pętla wykonuje.

Zamiast:

for( var i = 0 ; i< data.count ; i++){
}

Napisz:

var  count = data.count  ;
for( var i = 0 ; i< count ; i++){
}

Warunek końca pętli:  i< count sprawdza czy wyrażenie i< count == true, a więc wykonuje podwójne porównanie.

Więc zamiast:

for( var i = 0 ; i< data.count ; i++){
}

Napisz:

var  count = data.count  ;
for( var i = count ;   i-- ; ){
}

Wszystkie pętle typu forEach ( wliczając w to dostępne w bibliotekach np. JQuery ) są wolniejsze od standardowych pętli. Należy więc rozważyć ich zmianę na standardowe pętle przynajmniej w krytycznych częściach naszej aplikacji.

7. DOM

Pamiętaj o tym, że dostęp do obiektów DOM jest bardzo wolny.

Unikaj więc:

var divs = document.getElementsByTagName("div");
for( var i = 0 ; i < divs.length ; i++) {
}

Stosując:

var divs = document.getElementsByTagName("div");
for( var i = 0 , len = divs.length ; i < len ; i++) {
}

Jeżeli jesteś zmuszony do częstego odwoływania się do zbiorów elementów, rozważ przepisanie ich do tablicy ( dostęp do tablicy będzie wydajniejszy).

8. Zmiana layoutu

Każda zmiana dokonywana przez nas w DOM ( dodawanie nowych bloków ) , zmiany w CSS’sie wymuszają na przeglądarce ponowne przeliczenie pozycji elementów strony. Więcej na temat reflow.

Zamiast:

element.style.height = "100px";
element.style.display= "block";
element.style.fontSize= "14px";

Użyj:

.new_style{
height: 100px;
display: block;
font-size: 14px;
}
element.className = "new_style";

Ograniczysz w ten sposób ilość „odświeżeń” z trzech do jednego.

9. Uruchomienie JS w tle.

Jeżeli dokonaliśmy już wszelkich możliwych poprawek, ale dalej nie jesteśmy zadowoleni z wyników, możemy postarać się aby nasza aplikacja nie przeszkadzała użytkownikom. Sposoby, które nam w tym pomogą:

  • Uruchomienie krytycznych fragmentów kodu ( lub całych funkcji ) „w tle” za pomocą

setTimeout( 'fun()’ , 1 );

sprawi, że nie będziemy czekali na skończenie wykonywania funkcji fun().

  • Importowanie pliku z naszym kodem na końcu strony tuż przed </body> nie będzie spowalniało ładowania się zawartości strony.

10. Na koniec

Jednym z ostatnich zabiegów jakie możemy zrobić jest archiwizacja pliku z kodem JavaScript za pomocą JSMin, który m.in. usunie z pliku niepotrzebne komentarze oraz białe znaki.


Opracowane na podstawie:  Speed Up Your JavaScript

javascript

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.


*