読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

[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個

計測コード

結果
階層1x10000 階層4x2500 階層10x1000 階層40x250 階層100x100 階層400x25 階層1000x10
Firefox3.6 752.6ms 452.6ms 336.8ms 345.2ms 423.2ms 654.8ms 949.6ms
IE8 935.0ms 617.6ms 620.0ms 697.0ms 734.4ms 1093.6ms 1680.4ms


  • 多量の要素をフラットに並べたり、極端に深い階層を作ると遅くなる傾向。

計測3: spanとdiv

  • span と div をそれぞれ階層100x100個作る。

計測コード

結果
div span
Firefox3.6 451.0ms 284.4ms
IE8 699.6ms 950.6ms

おまけ: CSS

  • CSSセレクタをいろいろ試す。
    • CSSなし
    • div {...}
    • body div * {...}
    • div.class5 {...}
    • .class5 {...}
    • #id100 {...}

計測コード。

結果
CSSなし div body div * div.class5 .class5 #id100
Firefox3.6 432.4ms 463.2ms 578.6ms 407.0ms 430.2ms 440.2ms
IE8 570.2ms 696.6ms 862.2ms 584.8ms 582.6ms 573.2ms
  • 微妙。全称セレクタがやや重いかな、といったところ。

計測環境

最後に、計測に使用した環境は以下です。