Optymalizacja javascript - zbiór trików

Przedstawię różne sposoby zwiększające wydajność kodu javascript oraz/i zmniejszające jego objętość. Skoncentruję się głównie na przykładach bez zbędnych opisów. Techniki optymalizacji wydajności oraz zmniejszające ilość kodu:

1) Cachowanie właściwości length tablicy przy przechodzeniu przez pętle

tzn. należy użyć poniższego kodu
var myLength = myArray.length;

for (var i = 0; i < myLength; i++) {

}
zamiast
for (var i = 0; i < myArray.length; i++)
{
}

2) Dokładamy zawartość do DOM w trybie offline.

Spójrz na poniższe przykłady. Drugi przykład jest wydajniejszy.
var ul;
for (var i = 0; i < len; i += 1)
{
ul.appendChild(document.createElement('li'));
}
var ul;
var li = document.createElement('li');
var parent = ul.parentNode;
parent.removeChild(ul);
for (var i = 0; i < len; i += 1)
{
ul.appendChil(li.cloneNode(true));
}
parent.appendChild(ul);

3) Używaj arkusza CSS do zmiany wyglądu elementów.

Zamiast pisać
document.getElementById('jakis_id').backgroundColor="blue";
lepiej zdefiniować klasę w arkuszu css i w javascript napisać
document.getElementById('jakis_id').className = 'niebieski';

4) Deklarowanie zmiennych w jednej linii (jedno słowo var).

var a = 2, s = 'napis', x, y;
a nie
var a = 2;
var s = 'napis';
var x;
var y;

5) Optymalizacja warunków i wyrażeń.

// standardowy warunek if
if (type == 'foo' || type == 'bar') { ... }

// lepsze rozwiązanie
if (/^(foo|bar)$/.test(type)) { ... }
Jeśli chodzi o wyrażenia to należy zwrócić uwagę jaka zmienna lub wyrażenie jest pierwsza przy stosowaniu operatorów logicznych. Najlepiej pokaże to poniższy przykład.
var a = false, b = 50;
if (b && a) {//jest sobie warunek
}
if (a && b) {//to będzie szybsze bo a jest false i dalsza część nie będzie sprawdzana
}

6) Minimalizacja dostępu do właściwości.

Jeśli potrzebujesz uzyskać dostęp do właściwości obiektu więcej niż raz w skrypcie dobrze jest zapisać je pod zmienną.
var loc = window.location.href;

7) Minimalizacja iteracji pętli, używanie odwrotnych pętli.

/* Normalna pętla */
var i = 0;
while ( i < length ) {
    i++;
}

/* Odwrotna pętla */

var i = length;
while (i--) {//połączenie warunku kontroli pętli ze zmianami iteracji
//powoduje, że ta pętla jest szybsza
}

8) Minimalizuj reflow dokumentu poprzez ograniczenie liczby zmian DOM. (patrz też pkt. 2)

9) Operacje bitowe czasem mogą być przydatne.

Użyj ~~ zamiast Math.floor :) Poniższe zapisy są równoważne:
Math.floor(x)
x|0
~~x

10) Cachowanie obiektów.

Cachowanie często używanych obiektów globalnych zwiększa wydajność. Spójrzmy na poniższe listingi, z których drugi jest wydajniejszy. Np. Zamiast
for (var i = 1; i < 1000; i++)
{
Math.sin(i)*Math.cos(i);
}
lepiej napisać
var m = Math;
for (var i = 1; i < 1000; i++)
{
m.sin(i)*m.cos(i);
}

11) Używanie zmiennych lokalnych jest zawsze wydajniejsze niż zmiennych globalnych.

Spójrzmy na poniższe przykłady.
var str = '';
function global() {
    for (var i = 0; i < 100; i += 1) {
        str += i; // używamy tu zmiennej globalnej str
    }
}
global();
function local() {
    var i, str = '';
    for (i = 0; i < 100; i += 1) {
        str += i; // tu używamy zmiennej lokalnej (większa szybkość)
    }
}
local();

12) Ustawianie wartości zmiennych w warunkach if

Na przykład można zamienić kod
var moo = true;
var stuff = false;

if (moo) {
stuff = true;
}
na
var moo = true;
var stuff = false;

if (moo && stuff = true) {}

13) Minimalizacja kodu.

Najlepszym sposobem szybkiego zmiejszenia ilości kodu jest użycie jednego z tzw. minifikatorów kodu. Ja polecam narzędzie javascript compressor and comparison tool, które nie tylko ugniata kod ale też porównuje, który z popularnych minifikatorów jest dla naszego konkretnego kodu najlepszy.

14) Kompresja

15) Ładowanie javascript na końcu strony

16) Ograniczenie wywołań funkcji (szczególnie w pętlach)

tzn. zamiast poniższego kodu.
function do_3(n) {
return n*n*n;
}
for (var i = 1; i < 1000; i++)
{
do_3(i);
}
lepiej jest napisać coś takiego
for (var i = 1; i < 1000; i++)
{
i*i*i;
}

17) Literały kontra new.

Używanie literałów przy tworzeniu obiektów jest wydajniejsze tzn.
var tablica = [], obiekt = {};
zamiast
var tablica = new Array(), obiekt = new Object();

18) Unikajmy używania with.

Zamiast
with (obiekt) {
    foo = '123';
    bar = 'aaa';
}
lepiej napisać
var myObj = obiekt;
myObj.foo = '123';
myObj.bar = 'aaa';