DOM パフォーマンスが大幅に向上 - WebKit の innerHTML は 240% 高速になりました

一般的な DOM オペレーションの速度が大幅に向上したことを、心より嬉しく思います。WebKit レベルで変更が加えられたため、Safari(JavaScriptCore)と Chrome(V8)の両方のパフォーマンスが向上しました。

Chrome エンジニアの Kentaro Hara が WebKit 内で 7 件のコード最適化を行いました。その結果、JavaScript DOM アクセスがどれだけ高速化されたかを示しています。

DOM パフォーマンスの向上の概要

以下に、Hara Kentaro が作成したパッチの詳細を示します。リンク先は、テストケースを含む WebKit バグであるため、ご自身でテストをお試しいただけます。変更は WebKit r109829 と r111133 の間に行われました。Chrome 17 には含まれませんが、Chrome 19 には含まれています。

div.innerHTMLdiv.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.innerTextdiv.outerText のパフォーマンスを 4 倍に改善(V8/Mac)

このパッチでは、innerText の作成時の初期バッファサイズを変更しました。初期バッファサイズを 2^16 から 2^15 に変更することで、Chromium/Mac のパフォーマンスが 4 倍に向上しました。この違いは、基盤となる malloc システムによって異なります。

JavaScriptCore での CSS プロパティアクセスのパフォーマンスを 35%改善

CSS プロパティの文字列(.fontWeight.backgroundColor など)は、WebKit で整数 ID に変換されます。この変換は負荷が高いため、このパッチは、コンバージョンの結果をマップ(プロパティ文字列 => 整数 ID)にキャッシュに保存し、コンバージョンが複数回実行されないようにします。

テストの仕組み

プロパティへのアクセス時間を測定します。innerHTMLbugs.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 様と他のチームの皆様、お疲れ様でした。