insertRowとappendChild
これまで、tableに行やセルを追加する時は、標準で用意されているinsertRow()やinsertCell()を使っていたけれど、追加する度に再フローが発生してしまう関係か、createElement()してからappendChild()した方が、よっぽど早いことに気づいた。
具体的には、下記のコードでIE6とchromeで確認した。
var t = document.getElementById('t'); var tr,td; for(var i=0;i<100;i++){ tr = t.insertRow(i+1); for(var j=0;j<4;j++){ td = tr.insertCell(); td.innerText = i; } }
var doc = document; var w = doc.getElementById('w'); var tr,td; for(var i=0;i<100;i++){ tr = doc.createElement('tr'); for(var j=0;j<4;j++){ td = doc.createElement('td'); td.innerText = i; tr.appendChild(td); } w.appendChild(tr); }
行やセルの数が多くなればなるほど、性能差が顕著になってくる。
この例でも10倍程度の差が。
insert〜の方も、tableをdisplay:noneにしてからやれば誤魔化せるかなーと思ったけれど、再描画で時間を食うのか(それとも内部的にやっぱり再フローが発生してる?)期待した効果は現れず。
やはりノードに追加するタイミングを考慮できるappendChildに軍配が上がるか。
まあ、標準で用意されているメソッドを使うより、力技でやった方が早いことが多いのは、もはや基本だしね。
というわけで
var inhtml = []; for(var i=0;i<100;i++){ inhtml[i] = '<tr><td>'+i+'</td><td>'+i+'</td><td>'+i+'</td><td>'+i+'</td></tr>'; } document.getElementById('q').innerHTML = '<table border=1>'+inhtml.join('')+'</table>';
の方が更に早くなるのはナイショ。
あまりにもスマートじゃないことと、ブラウザやtableの規模によっては遅くなったりもするから、自分用のscriptぐらいでしかこんな力技は使わないけれど、速度差が顕著に出てくるような仕様を要求されたら、使わざるを得ない時も来るかもしれん。
未だにIE5を使ってるとか勘弁。
それ動的な描画とかネオジオCD並の速度だから。