[JavaScript] DOMエレメントの描画時間を計る
JavaScriptで生成したDOMエレメントの描画時間を計測したい。
そもそも描画時間の計測ってどうすればいいの?
とりあえず、innerHTMLの所要時間を計ってみる。
// DOM要素を10万個作成 var str = ""; for ( var i=1;i<=100000;i++ ) { str += "<div id='div"+i+"' class='"+ i%10 +"'>div"+i+"</div>" } // 計測 alert("start!!"); var start = new Date(); document.getElementById("out").innerHTML = str; var end = new Date(); // 結果を表示 document.getElementById("time").innerHTML = (end-start)/1000;
- Firefox3.6 : 体感だと3〜2秒くらいだけど、「1秒」と表示される。なんか早い・・・。
- IE8 : 体感4〜3秒,表示は0.8。明らかに早い・・・。
うーむ、どうもinnerHTMLの所要時間だけ計ってもダメっぽいなー、ということで調べて見ると以下の資料を発見。
Understanding Internet Explorer Rendering Behaviour
- レンダリングはJavaScriptの処理とは別にスケジューリングされて実行される。
- レンダリングタスクがキューに積まれ、順に実行されるらしい。
- タスクが積まれている状態でDOMエレメントのプロパティを参照すると、ブラウザはレンダリング処理を即時実行する。
- 正しい値を返すため、レンダリングタスクを処理してからプロパティ値を返す、という動きになるとのこと。
プロパティにアクセスする処理を追加してみる。
// DOM要素を10万個作成 var str = ""; for ( var i=1;i<=100000;i++ ) { str += "<div id='div"+i+"' class='"+ i%10 +"'>div"+i+"</div>" } // 計測 alert("start!!"); var start = new Date(); var out = document.getElementById("out"); out.innerHTML = str; out.offsetHeight; var end = new Date(); // 結果を表示 document.getElementById("time").innerHTML = (end-start)/1000;
確認はこちら。体感速度と同程度の時間が表示されるようになった。よしよし。
計測1: 要素数
- 要素数: 100, 500, 1000, 5000, 10000, 50000
- 100階層のdivを1〜500個作成し、表示されるまでの時間を計測。
※Benchmarkを使用しています。結果の見方はこちらを参照
結果
※5回試行した平均値です。
100 | 500 | 1000 | 5000 | 10000 | 50000 | |
---|---|---|---|---|---|---|
Firefox3.6 | 10.0ms | 22.8ms | 48.4ms | 214.6ms | 424.4ms | 2107.4ms |
IE8 | 13.0ms | 37.4ms | 71.2ms | 339.8ms | 680.4ms | 3541.0ms |
- 要素数に比例して線形増加。
計測2: 階層の深さ
- 要素数10000を階層の深さを変えて描画。
- 階層1のdivが10000個
- 階層4のdivが2500個
- 階層10のdivが1000個
- 階層40のdivが250個
- 階層100のdivが100個
- 階層400のdivが25個
- 階層1000のdivが10個
計測3: spanとdiv
- span と div をそれぞれ階層100x100個作る。
結果
div | span | |
---|---|---|
Firefox3.6 | 451.0ms | 284.4ms |
IE8 | 699.6ms | 950.6ms |
おまけ: CSS
計測コード。
計測環境
最後に、計測に使用した環境は以下です。
- CPU: Intel Core 2 Duo 2.53GHz
- メモリ: 4GB
- OS: Windows 7 Professional 64bit版
- Firefox: 3.6.13
- IE: 8.0.7600.16385