Toon posts:

[JS] Performance bij DOM wijzigingen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hey,

Het projectje waar ik op dit moment mee bezig ben heeft één hele grote pagina die erg langzaam is op dit moment. Het probleem is dat we soms over een stuk of 500 tables loopen en daar 6 DOM wijzigingen aanbrengen. Eigenlijk valt hier erg weinig aan te doen zover ik kan bedenken. Wat de JS doet is één veld showen, de rest hiden, aan de hand van een nummertje.

Op dit moment doen we elke keer dit:

code:
1
2
3
4
5
6
7
8
      case IETS:
        openDetailField(redenFld, statusDetailsContainer.rows[0]);
        closeDetailField(datumFld, statusDetailsContainer.rows[1]);
        closeDetailField(omschrijvingFld, statusDetailsContainer.rows[2]);
        closeDetailField(postcodeFld, statusDetailsContainer.rows[3]);
        closeDetailField(huisnrFld, statusDetailsContainer.rows[4]);
        closeDetailField(toevoegingFld, statusDetailsContainer.rows[5]);
        break;


We wijzigen dus elk veld, terwijl er eigenlijk maar ééntje hidden moest worden, en één geshowed moest worden. (er staat er altijd maar één, of geen, aan)

De open en close zien er alsvolgt uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
function closeDetailField(field, row) {
    field.value = "";
    row.style.display = "none";
}
function openDetailField(field, row) {
    field.disabled = null;
    if (IE) {
        row.style.display = "inline";
    } else {
        row.style.display = "table-row";
    }
}


Is het misschien de moeite waard om overal eerst een check te doen of ze toevallig al op de juiste waarde staan? Ik weet niet wat sneller is, het uitlezen en dan beslissen wat te doen, of het klakkeloos in de DOM veranderen.. Dan zouden we al snel 4 * 500 DOM-mutaties veranderen in leesacties + een IFje.

Heeft iemand misschien nog andere ideeën over hoe dit geoptimaliseerd kan worden? Het grootste probleem is dat de klant IE6 gebruikt, in Firefox kost het maar een fractie van de tijd.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op woensdag 16 mei 2007 @ 17:27:
Is het misschien de moeite waard om overal eerst een check te doen of ze toevallig al op de juiste waarde staan? Ik weet niet wat sneller is, het uitlezen en dan beslissen wat te doen, of het klakkeloos in de DOM veranderen.. Dan zouden we al snel 4 * 500 DOM-mutaties veranderen in leesacties + een IFje.
Wat ik me dan afvraag in eerste instantie: waarom probeeeeeer je het dan niet effe? Het is echt geen mega-klus om dat aan te passen, wel?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Verwijderd

Topicstarter
Nouja, opzich niet nee, ik ben het nu ook al aan het proberen.. Maar mocht het sneller zijn zou ik graag van iemand horen waarom het zo is.

En als ik het hier post komen misschien mensen met geniale oplossingen! (zal niet voor het eerst zijn)

Verwijderd

Topicstarter
Het lijkt trouwens niks uit te maken... dat is wel jammer. Maar daarbij wel gelijk de vraag:
Weet iemand anders een betere manier?

We zoeken nu door een lijst die we verkregen hebben met getElementsByTagName, en daar lopen we specifiek doorheen soms om de velden aan te passen.

  • mux
  • Registratie: Januari 2007
  • Laatst online: 19-11 16:51

mux

99% efficient!

Ligt aan de interpreter. MSXML parser is vrij dom en is behoorlijk high-level (interpreteert dus echt), ik heb het idee dat opera een soort jit-compiler of in ieder geval een hele slimme optimizer gebruikt en firefox zit er tussenin. Sowieso zijn DOM-acties behoorlijk snel in elke browser, maar het heeft *altijd* zin om je code verder te optimaliseren en het 'makkelijker' te maken voor je browser. Je moet niet "uitgaan" van optimalisaties, liefst moet je zelf optimaal coden. En dat is hier behoorlijk makkelijk lijkt me?

  • mux
  • Registratie: Januari 2007
  • Laatst online: 19-11 16:51

mux

99% efficient!

Verwijderd schreef op woensdag 16 mei 2007 @ 17:37:
Het lijkt trouwens niks uit te maken... dat is wel jammer. Maar daarbij wel gelijk de vraag:
Weet iemand anders een betere manier?

We zoeken nu door een lijst die we verkregen hebben met getElementsByTagName, en daar lopen we specifiek doorheen soms om de velden aan te passen.
sorry voor de twee posts achter elkaar, maar getelementsbytagname is de facto standaard, niet echte standaard, en geeft (helaas) wisselende resultaten. Het is misschien handiger om systematische id's en getElementById te gebruiken.

Of is het wel standaard? Ik dacht namelijk van niet.

Verwijderd

Topicstarter
Ik kan mijn vinger nog niet echt op de preciese pijnpunten leggen. In de tussentijd probeer ik zoveel mogelijk dingen uit.

Maar mochten mensen vreemde dingen zien, of veel gemaakte JS fouten hoor ik het graag natuurlijk.

We proberen wel de code zo optimaal mogelijk op te zetten. Maar daar hebben al verschillende mensen naar gekeken. We hebben ons erbij neergelegd dat het waarschijnlijk op deze manier nooit echt super snel zal worden, maar elke winst is uhhm winst!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Ik denk dat zowieso de acties die uitgevoerd worden op het DOM (dus die wijzigingen aanbrengen in de view) trager worden in IE naarmate het document an sich groter is (er moet dan meer 'gecontroleerd' worden voor herpositionering e.d.) Kun je het document niet in wat kleinere stukken hakken? Of misschien server-side de juiste elementen bepalen en die uitpoepen?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Verwijderd

Topicstarter
Hmm.. jakkes! Ik zie nu net dat een andere functie dan ik gedacht (gehoopt!) had de performance zo ver omlaag haalt.

Blijkbaar hebben we een functie die bij elke checkbox op de pagina (en dat zijn er nogal wat) een functie in de onclick zet. Deze functie reageert op de shifttoets en creeërt een soort multiselect optie.

Dat is wel een beetje jammer, bij elke checkbox wordt er een stuk of 10 regels javascript code aangehangen!!

  • mux
  • Registratie: Januari 2007
  • Laatst online: 19-11 16:51

mux

99% efficient!

Ja, ik weet in ieder geval te zeggen dat IE heel slecht is in closures: als er veel code in je pagina zit die niet altijd een functie heeft zal IE er belachelijk inefficient mee omspringen. Je moet vrij knap programmeren om erachter te komen hoe je grote volumes code kunt optimaliseren. Ik ben daar ook mee bezig geweest en heb samen met een vriend wat simpel spul kunnen onderzoeken.

Enige jammere is dat ik een hoop daarvan in mn project heb gestopt waar ik nu mee bezig ben, maar dat is betaald voor een bedrijf welke de rechten op de code bezit. Anders had je er wel naar kunnen kijken, was een stuk sneller geweest dan specifieke dingen uitleggen op het forum :-s

Verwijderd

Topicstarter
De code die erg traag is dat is de volgende code:

code:
1
2
3
4
5
6
            for (var i = 0; i < elems.length; i++) {
                if (elems[i].type == "checkbox") {
                    totaalAantalChechboxes++;
                                elems[i].onclick = shiftClick;
                }
            }


Het probleem is dus dat hij door ALLE elementen van de DOM heenloopt. En dat willen we absoluut niet denk ik. Er moet gewoon een betere manier zijn om dit te doen. Weet iemand misschien een goede DOM-doorloop tutorial?

Wat we doorlopen is een normale table met tr'en. Ik weet dat de checkbox altijd de eerste child van de tr is... Met die informatie moet toch makkelijker door de checkboxen heen gelooped kunnen worden?

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Verwijderd schreef op woensdag 16 mei 2007 @ 18:25:
De code die erg traag is dat is de volgende code:

code:
1
2
3
4
5
6
            for (var i = 0; i < elems.length; i++) {
                if (elems[i].type == "checkbox") {
                    totaalAantalChechboxes++;
                                elems[i].onclick = shiftClick;
                }
            }


Het probleem is dus dat hij door ALLE elementen van de DOM heenloopt. En dat willen we absoluut niet denk ik. Er moet gewoon een betere manier zijn om dit te doen. Weet iemand misschien een goede DOM-doorloop tutorial?

Wat we doorlopen is een normale table met tr'en. Ik weet dat de checkbox altijd de eerste child van de tr is... Met die informatie moet toch makkelijker door de checkboxen heen gelooped kunnen worden?
document.getElementsByTagName('INPUT') ?

Verder, als je veel met DOM mutaties bezig bent, kijk dan eens naar MooTools Dat maakt werken met de DOM sexy en lekker rap O+

zo kan je bijv:

JavaScript:
1
2
3
4
$$('Table TR').each(function(el)
{
el.getChilds()[5].setStyle('display', 'none');
});

[ Voor 5% gewijzigd door SchizoDuckie op 16-05-2007 18:35 ]

Stop uploading passwords to Github!


  • mithras
  • Registratie: Maart 2003
  • Niet online
Je hebt altijd 1 of geen element open staan. Als je nu gewoon 2 variabelen hebt, een die je gaat openen en een die open is. Is "degene die open is" gevuld (niet null, null betekent alles gesloten), dan moet je die sluiten.
Vervolgens open je het element wat je wil openen en stop je dat id in "degene die open is". En zo kan je door blijven klikken.

Op zich niet fail-safe, gezien er misschien op een andere manier "toevallig" een element open gezet kan worden en dit dus niet meer werkt. Maar zo hoef je wel maar twee DOM acties uit te voeren, in plaats van alle elementen langs lopen :)

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
mithras schreef op woensdag 16 mei 2007 @ 18:31:
Op zich niet fail-safe, gezien er misschien op een andere manier "toevallig" een element open gezet kan worden...
Dat is natuurlijk een kwestie van consequent de 'openfoo' en 'closefoo' functies aanroepen en zorgen dat die functies de var bijwerken ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • mithras
  • Registratie: Maart 2003
  • Niet online
RobIII schreef op woensdag 16 mei 2007 @ 18:34:
[...]

Dat is natuurlijk een kwestie van consequent de 'openfoo' en 'closefoo' functies aanroepen en zorgen dat die functies de var bijwerken ;)
Maar stel je breidt het systeem uit, en er komen wat extra mogelijkheden. Bij update #3 van je systeem open je bij een andere actie ook een element. En ineens gaan er vreemde dingen gebeuren...

Ik zou het wel gewoon zo doen, maar met álles aflopen ben je er 100% zeker van dat ze dicht zitten. Hierbij ben je het 99.9% zeker. Ben je zo stom om in die 0.1% marge te gaan stoeien is het je eigen fout, maar wel belangrijk om te realiseren :)

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
mithras schreef op woensdag 16 mei 2007 @ 20:43:
[...]
Maar stel je breidt het systeem uit, en er komen wat extra mogelijkheden. Bij update #3 van je systeem open je bij een andere actie ook een element. En ineens gaan er vreemde dingen gebeuren...
Niet als je in die actie om die x en y en z doet daarna de openfoo() functie gebruikt en dus wezenlijk gebruik maakt van de functionaliteit die er is (zeg maar API / Framework).
mithras schreef op woensdag 16 mei 2007 @ 20:43:
Ik zou het wel gewoon zo doen, maar met álles aflopen ben je er 100% zeker van dat ze dicht zitten. Hierbij ben je het 99.9% zeker. Ben je zo stom om in die 0.1% marge te gaan stoeien is het je eigen fout, maar wel belangrijk om te realiseren :)
Uiteraard; daarom zei ik ook expliciet 'consequent'. Je moet jezelf (en je team) wel een beetje een consequente stijl aanleren.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Pagina: 1