JS benchmark: sok elem beszúrása az oldalba
Igazából nincs semmi kérdésem, csak gondoltam megosztom veletek, hogy mit csináltam :)
Kíváncsi voltam, hogy ha JS-ben szeretném legenerálni az oldal egy részét, akkor vajon milyen módszerrel érdemes. Az alábbi ötleteim támadtak:
1. createElement + appendChild
2. Létrehozom a stringet, pl "<div></div><div></div>...", és innerHTML-lel "adom" hozzá.
3. Rögtön az innerHTML-t bővítgetem
Továbbá felmerült az is, hogy vajon hogyan érdemes a stílus paramétereket megadni az új elemnek.
1. setAttribute('style', '[komplett stílus]'). Itt van egy olyan probléma, hogy IE alatt ez a megoldás nem működik. Lásd: http://www.quirksmode.org/dom/w3c_core.html és http://www.quirksmode.org/bugreports/archives/2005/03/setAttribute_does_not_work_in_IE_when_used_with_th.html . A probléma megoldását az utóbbiról vettem. (lásd forrás)
2. Egyesével végigmegyek és obj.style.[tulajdonság] = 'érték' megoldást használom.
3. "Stringes" esetben persze az előző kettő opció nem játszik.
A mérés WinXP Prof operációs rendszer alatt készült, a táblázatban az értékek ms-ok, és a kisebb érték a jobb. 10 000 div-et kellett beszúrniuk.
A tapasztalatok:
- A string + innerHTML megoldás annyira lassú minden böngészőben, hogy megkockáztatom a kijelentést: Soha ne használd arra, hogy "HTML elemekkel" így bővítsd az oldalt. A forrásból ki is hagytam ezt a tesztet, mert 1000 div esetén FF és IE is rendesen megizzad, a többin nem is próbáltam, már csak 100-zal.
- Amint a táblázatból kitűnik, minden böngészőben van különbség a két eljárás között, és általában a setAttribute() megoldás előnyére (még ha néha elég kicsi is)
- Az eredmények 4-4 mérés átlagából származnak, kivéve Opera, ahol akkora volt a szórás, hogy inkább 5-öt mértem :D Operánál eléggé ingadozott, a többinél folyamatosan ugyanazok az értékek jöttek nagyjából.
- Érdekes, hogy Safarinál a "style" módon stílusozott elemeket sokkal lassabban adja hozzá az oldalhoz. Ez a jelenség akkor is tapasztalható volt, ha felcseréltem a tesztek futásának sorrendjét. (94 ms vs 664 ms)
- További érdekesség még, hogy FF3 alatt az ilyen elemeket sokkal lassabban hozza létre! (485 ms vs 858 ms)
Forrás:Ui:
Ez nem működik :$ Vagy én csináltam vmit rosszul :?
■ Kíváncsi voltam, hogy ha JS-ben szeretném legenerálni az oldal egy részét, akkor vajon milyen módszerrel érdemes. Az alábbi ötleteim támadtak:
1. createElement + appendChild
2. Létrehozom a stringet, pl "<div></div><div></div>...", és innerHTML-lel "adom" hozzá.
3. Rögtön az innerHTML-t bővítgetem
Továbbá felmerült az is, hogy vajon hogyan érdemes a stílus paramétereket megadni az új elemnek.
1. setAttribute('style', '[komplett stílus]'). Itt van egy olyan probléma, hogy IE alatt ez a megoldás nem működik. Lásd: http://www.quirksmode.org/dom/w3c_core.html és http://www.quirksmode.org/bugreports/archives/2005/03/setAttribute_does_not_work_in_IE_when_used_with_th.html . A probléma megoldását az utóbbiról vettem. (lásd forrás)
2. Egyesével végigmegyek és obj.style.[tulajdonság] = 'érték' megoldást használom.
3. "Stringes" esetben persze az előző kettő opció nem játszik.
A mérés WinXP Prof operációs rendszer alatt készült, a táblázatban az értékek ms-ok, és a kisebb érték a jobb. 10 000 div-et kellett beszúrniuk.
A tapasztalatok:
- A string + innerHTML megoldás annyira lassú minden böngészőben, hogy megkockáztatom a kijelentést: Soha ne használd arra, hogy "HTML elemekkel" így bővítsd az oldalt. A forrásból ki is hagytam ezt a tesztet, mert 1000 div esetén FF és IE is rendesen megizzad, a többin nem is próbáltam, már csak 100-zal.
- Amint a táblázatból kitűnik, minden böngészőben van különbség a két eljárás között, és általában a setAttribute() megoldás előnyére (még ha néha elég kicsi is)
IE6 | IE7 | FF3 | Opera 9.26 | Safari 3.1.2 | |
---|---|---|---|---|---|
setAttribute() | 1068 | 1271 | 485 | 1700 | 453 |
appendChild() | 234 | 156 | 334 | 344 | 94 |
style | 1188 | 1391 | 858 | 1618 | 523 |
appendChild() | 234 | 156 | 348 | 279 | 664 |
- Az eredmények 4-4 mérés átlagából származnak, kivéve Opera, ahol akkora volt a szórás, hogy inkább 5-öt mértem :D Operánál eléggé ingadozott, a többinél folyamatosan ugyanazok az értékek jöttek nagyjából.
- Érdekes, hogy Safarinál a "style" módon stílusozott elemeket sokkal lassabban adja hozzá az oldalhoz. Ez a jelenség akkor is tapasztalható volt, ha felcseréltem a tesztek futásának sorrendjét. (94 ms vs 664 ms)
- További érdekesség még, hogy FF3 alatt az ilyen elemeket sokkal lassabban hozza létre! (485 ms vs 858 ms)
Forrás:
<html>
<head>
<title>JS Benchmark</title>
<script>
function test() {
var n, matrix;
n = 10000;
matrix = [];
t = [];
// Mátrix léterhozása
t.push(new Date());
for(i=0;i<n;i++) {
matrix[i] = document.createElement('div');
matrix[i].setAttribute('id', 'div'+i);
if(document.all) {
matrix[i].style.cssText = 'border: 1px solid black; width: 2px; height: 2px';
} else {
matrix[i].setAttribute('style', 'border: 1px solid black; width: 2px; height: 2px');
}
}
t.push(new Date());
// Megjelenítés
c = document.getElementById('container');
t.push(new Date());
for(i=0;i<n;i++) {
c.appendChild(matrix[i]);
}
t.push(new Date());
// Tartalom törlése
c.innerHTML = '';
// Mátrix léterhozása
t.push(new Date());
for(i=0;i<n;i++) {
matrix[i] = document.createElement('div');
matrix[i].setAttribute('id', 'div'+i);
matrix[i].style.border = '1px solid black';
matrix[i].style.width = '2px';
matrix[i].style.height = '2px';
}
t.push(new Date());
// Megjelenítés
c = document.getElementById('container');
t.push(new Date());
for(i=0;i<n;i++) {
c.appendChild(matrix[i]);
}
t.push(new Date());
document.getElementById('value1').innerHTML = (t[1].getTime()-t[0].getTime()) + ' ms';
document.getElementById('value2').innerHTML = (t[3].getTime()-t[2].getTime()) + ' ms';
document.getElementById('value3').innerHTML = (t[5].getTime()-t[4].getTime()) + ' ms';
document.getElementById('value4').innerHTML = (t[7].getTime()-t[6].getTime()) + ' ms';
}
window.onload = test;
</script>
</head>
<body>
<h1>document.createElement() + setAttribute('style', '...')</h1>
<div id="value1"></div>
<h1>container.appendChild()</h1>
<div id="value2"></div>
<hr/>
<h1>document.createElement() + style.[...] = '...'</h1>
<div id="value3"></div>
<h1>container.appendChild()</h1>
<div id="value4"></div>
<h2>Container</h2>
<div id="container"></div>
</body>
</html>
A BBEditor a szövegszerkesztőből vagy böngészőből másolt tabokkal elválasztott cellás formázását tudja táblázattá alakítani automatikusan.
Ez nem működik :$ Vagy én csináltam vmit rosszul :?
A string + innerHTML megoldás annyira lassú minden böngésző
mátrix feltöltése 10000 elemnél is < 100 ms, 1000 elemnél már elhanyaglható 0-20ms különböző böngészőkben, innerHTML töltési idő nagyjából 1/2 az appendChilld-hez képest, inline stílusbeállítást nem használtam, gyakorlatban is alábbi módon töltök
másrészt most ébredtem bővel lehet, hogy vmit benéztem :))
Though this analysis, a number of things about string performance have been observed:
* Native string operations in all browsers have been optimized to the point where borrowing techniques from other languages (such as passing around a single buffer for use by many methods) is for the most part unneeded.
* Array.join still seems to be the fastest method with Internet Explorer; either += or String.prototype.concat.apply(”", arguments) work best for all other browsers.
* Firefox has definite issues with accessing argument members via dynamic/variables
* And of course, the reminder to not ignore the data
fent én is az Array.join-t használtam
üdv Csaba
Wow
- nem adtál id attributumot a diveknek
- class-t használtál nem pedig style-t, ami szintén gyorsított
FF3 alatt hozzáadva ezt a két dolgot (5, 249)-ről (18, 541)-re változott az eredmény! De még így is gyorsabb volt úgy 40%-al.
Tudom, hogy a class gyorsabb egyébként, de nem életszerű, hogy üres diveket akar az ember beszúrkálni, ugyanolyan tulajdonsággal. Legalábbis nálam nem ez a helyzet :)
Egyébként a "javascript benchmark dom"-ra rákeresve jó sok ilyen cuccot találtam, de ez a szóhármas csak ma jutott eszembe... Itt van egy rossz példa az innerHTML használatra: http://andrew.hedges.name/experiments/innerhtml/ . Nekem nagyságrendekkel több jött ki innerHTML-re. Most így elsőre nem is látom, hogy miért :-/ Nah, mindegy :)
http://www.liligo.hu/
üdv Csaba
jav: márha vannak találatok, szóval a http://www.liligo.fr -en