IE8の『IE8標準準拠モード』のパフォーマンスがビックリするほど悪い
ここ1ヶ月ほど、IE8のみをターゲットとした業務Webアプリ開発のお仕事をしてるんだけど、IE8で異常にパフォーマンスが劣化する問題に遭遇した。
現象
- よくありがちな「ヘッダ固定テーブル」
- 1行目およびN列を固定→<table>を4分割
- マウスオーバー行の背景色を変える
- マウスオーバーはclassNameを書き換えることで実装
- 表示件数は数百行程度
ざっくり言うとこんなようなものを実装したところ、マウスオーバーが実用にならないレベルでモッサリとしてしまった。ログを取ったりして状況を調べてみたところ、DOMアクセス自体にはまったく問題がないのだが、classNameを書き換えた際の再描画パフォーマンスが非常に悪いところまでわかった。
原因っぽいもの
「じゃあ何で再描画が遅いの?」ということについて色々調べたところ、IE8の『IE8標準準拠モード』のパフォーマンスに問題があるっぽいという情報を見つけた。
ブラウザはWindows IE8限定とします。
HTMLファイルのDOCTYPE宣言によって標準準拠/後方互換モードを切り替えられますが、
下記JavaScriptをそれぞれで走らせた場合、明らかに標準準拠モードが遅いです。for (var i = 0; i < 10000; i++)
標準準拠モードと後方互換モードのJavaScriptのパフォーマンスに - JavaScript - 教えて!goo
{
var t = document.createTextNode(i + ", ");
var o = document.createElement("div").appendChild(t);
document.getElementById("test").appendChild(o);
}
これを見る限りではレンダリングだけではなく、JavaScript自体のパフォーマンスにも影響がでているようである。
検証コード
IE8で動作させてください。console.log()を使ってるのでF12で開発者ツールを表示させないとエラーが出るかも。
<!DOCTYPE html> <html lang="ja"> <head> <meta http-equiv="X-UA-Compatible" content="IE=8"> <script type="text/javascript"> window.onload = function () { var start = new Date().getTime(); var buf = [], i = 10000; buf.push('<div><table>'); while (i--) { buf.push('<tr onmouseover="mouseover(event, this)" onmouseout="mouseout(event, this)"><td>a</td><td>b</td><td>c</td></tr>'); } buf.push('</table></div>'); document.body.innerHTML = buf.join(''); setTimeout(function () { console.log(new Date().getTime() - start); }, 0); } function mouseover(event, currentTarget) { (event.currentTarget || currentTarget).style.backgroundColor = 'red'; } function mouseout(event, currentTarget) { (event.currentTarget || currentTarget).style.backgroundColor = ''; } </script> <style> div { width:300px; height:300px; overflow:scroll; } table { width: 500px; } td { border: 1px solid black; } </style> </head> <body> </body> </html>
実行時間(初期表示にかかる時間)
IE8標準準拠モード | 2213[msec] |
IE7標準準拠モード | 1348[msec] |
Quirksモード | 1150[msec] |
まとめ
検証コードではElement.style.backgroundColorで背景色を変えているが、私が実際に地雷を踏んだケースでは、「比較的煩雑なCSSを使っている」状態で「classNameのON/OFFで背景色を切り替えた」ところ、数百行程度でパフォーマンス問題が発生してしまっていた。検証コードでは『IE7標準準拠モード』でも比較的良いパフォーマンスが出ているのだが、私のケースではそれではダメで『Quirksモード』ではOKという状況である。
今回の検証コードではその点については深く調査していないのだが、どうやらCSS解釈自体も遅くなるようなので、パフォーマンスを気にするようなアプリを作る際に『Quirksモード』で作らざるを得ないようだ。