一般的な DOM オペレーションの速度が大幅に向上したことを、心より嬉しく思います。WebKit レベルで変更が加えられたため、Safari(JavaScriptCore)と Chrome(V8)の両方のパフォーマンスが向上しました。
Chrome エンジニアの Kentaro Hara が WebKit 内で 7 件のコード最適化を行いました。その結果、JavaScript DOM アクセスがどれだけ高速化されたかを示しています。
DOM パフォーマンスの向上の概要
div.innerHTML
とdiv.outerHTML
のパフォーマンスが 2.4 倍向上(V8、JavaScriptCore)- Chromium/Mac での
div.innerText
とdiv.outerText
のパフォーマンスが4 倍に向上(V8/Mac) - CSS プロパティへのアクセスが35% 向上(JavaScriptCore)
div.classList
、div.dataset
、div.attributes
のパフォーマンスが最大 10.9 倍向上(V8)div.firstElementChild
、lastElementChild
、previousElementSibling
、nextElementSibling
のパフォーマンスが 7.1 倍向上(V8)- V8 DOM 属性へのアクセスが 4 ~ 5% 向上(V8)
以下に、Hara Kentaro が作成したパッチの詳細を示します。リンク先は、テストケースを含む WebKit バグであるため、ご自身でテストをお試しいただけます。変更は WebKit r109829 と r111133 の間に行われました。Chrome 17 には含まれませんが、Chrome 19 には含まれています。
div.innerHTML
と div.outerHTML
のパフォーマンスを 2.4 倍に改善(V8、JavaScriptCore)
WebKit での以前の動作:
- タグごとに文字列を作成します。
- 作成した文字列を
Vector<string>
に追加し、DOM ツリーを解析します。 - 解析後、
Vector<string>
内のすべての文字列の合計サイズの文字列を割り当てます。 Vector<string>
内のすべての文字列を連結し、innerHTML
として返します。
WebKit の新しい動作:
1. 1 つの文字列(S など)を割り当てます。1. タグごとに文字列を S に連結し、DOM ツリーを段階的に解析します。1. S を innerHTML
として返します。
要するに、多くの文字列を作成して連結するのではなく、1 つの文字列を作成し、文字列を段階的に追加します。
Chromium/Mac の div.innerText
と div.outerText
のパフォーマンスを 4 倍に改善(V8/Mac)
このパッチでは、innerText
の作成時の初期バッファサイズを変更しました。初期バッファサイズを 2^16 から 2^15 に変更することで、Chromium/Mac のパフォーマンスが 4 倍に向上しました。この違いは、基盤となる malloc システムによって異なります。
JavaScriptCore での CSS プロパティアクセスのパフォーマンスを 35%改善
CSS プロパティの文字列(.fontWeight
、.backgroundColor
など)は、WebKit で整数 ID に変換されます。この変換は負荷が高いため、このパッチは、コンバージョンの結果をマップ(プロパティ文字列 => 整数 ID)にキャッシュに保存し、コンバージョンが複数回実行されないようにします。
テストの仕組み
プロパティへのアクセス時間を測定します。innerHTML
(bugs.webkit.org/show_bug.cgi?id=81214 のパフォーマンス テスト)の場合、テストでは次のコードの実行時間のみが測定されます。
for (var i = 0; i < 1000000; i++)
document.body.innerHTML;
パフォーマンス テストでは、HTML 仕様からコピーした大きなボディを使用します。
同様に、CSS プロパティ アクセス テストは、次のコードの時間を測定します。
var spanStyle = span.style;
for (var i = 0; i < 1000000; i++) {
spanStyle.invalidFontWeight;
spanStyle.invalidColor;
spanStyle.invalidBackgroundColor;
spanStyle.invalidDisplay;
}
幸い、他の重要な DOM 属性とメソッドでもパフォーマンスをさらに改善できると、ケンタロウ ハラ氏は考えています。
かかってこい!
Haraken 様と他のチームの皆様、お疲れ様でした。