Bättre prestanda på dina javascript

Det finns några enkla knep för att få bättre prestanda på dina javascript och jag vill i detta inlägg ge några konkreta exempel på vad.

Om vi tänker oss nedanstående kod som bara skapar en variabel och hämtar ett värde från en funktion och adder ett till detta innan det returneras.

function useVar(){
    localVariable = getSomeValue();
    return (localVariable + 1);
}

Det som händer här är att den att försöka hitta variabeln localVariable någon annanstans i koden än i den aktuella funktionen useVar. Först går den utanför funktionen och letar i det aktuella objektet (om det finns något), sedan går den vidare i hierarkin och kommer leta igenom hela DOM. Dessutom gör den det två gånger i vårt exempel eftersom vi först ger den ett värde och sedan använder vi samma variabel för att addera värdet.

Om vi istället lägger till var så talar vi om för javascript att variabeln är lokal och behöver därför inte gå igenom all kod för att leta efter en liknande variabel.

function useVar(){
    var localVariable = getSomeValue();
    return (localVariable + 1);
}

Samma sak gäller när du loopar

for(var i=0;i < 10;i++){
  //>
}

Om du dessutom itererar igenom en kollektion skall du placera längden av kollektionen i en lokal variabel innan du stoppar in den i din for-sats.

var items = myObject.length;
for(var i=0;i < items ;i++){
 //>
}

Normalt vill man placera myObject.length i for-satsen, men då kommer den att räkna antalet poster i din kollektion vid varje iteration. Detta är givetvis kostsamt och bör undvikas.

En annan sak man vill undvika är att arbeta mot properties av sidelement.
Vi kan ta följande kod som exempel.

function updateUI(){
    var element = document.getElementById('myElement');
    element.innerHTML = '';
    element.innerHTML += getHeader();
    element.innerHTML += getText();
}

Ovanstående exempel skapar 5 referenser (uppslagningar) mot innerHTML. En där vi sätter värdet till tom sträng. Sedan två när vi sätter rubrik (en för att hämta värdet och sedan en ytterligare för att sätta ett nytt värde), samt två till när texten skrivs.
Det man istället vill göra är att bygga upp allt innehåll i en lokal variabel och gå direkt mot innerHTML en gång.

function updateUI(){
    var element = document.getElementById('myElement');
    var content = getHeader() + getText();

    element.innerHTML = content;
}

När man jobbar mot mot kollektioner av element som befinner sig i en hierarki kan man cacha elementkollektionen och därigenom få bättre prestanda.

Exempel på detta kan vara.

function updateUI(){
    var value1 = document.body.all.myElement1.value = 1;
    var value2 = document.body.all.myElement2.value = 3;
    document.body.all.myElement3.value = value1+value2;
}

Problemet med ovanstående är att varje gång man anropar ett element så kommer den att gå igenom hela hierarkin. Alltså i princip på detta sätt.
– hitta dokumentet
– hitta bodyelementet i dokumentet
– ge mig en kollektion av alla element i bodyelementet i dokumentet.

Det man då kan göra är att cacha hela denna kedjan i en lokal variabel och slippa denna typ av uppslagning varje gång. Då får man istället en pekare som direkt kan hämta rätt värden/element.

function updateUI(){
    var elements = document.body.all;
    var value1 = elements.myElement1.value = 1;
    var value2 = elements.myElement2.value = 3;
    elements.myElement3.value = value1+value2;
}

När man jobbar med JSON så vill man objektifiera den strängen. Det kan exempelvis göras med eval() men det är inte att rekommendera. Detta eftersom den inte har någon som helst säkerhet och kör i princip all kod direkt vilket kan vara skadligt för din sida. Istället kan man använda något bibliotek som är säkrare, men oftast inte speciellt mycket snabbare. Med internet explorer 8 finns en metod JSON.stringify att objektifiera json-strängen med bra säkerhet och bra prestanda. Men det är ju knappt användbart innan fler webbläsare har implementerat det.

Kommentarer inaktiverade.

%d bloggare gillar detta: