嬉しいことに、一般的な DOM 操作のスピードが飛躍的に向上しています。WebKit レベルでの変更により、Safari(JavaScriptCore)と Chrome(V8)のパフォーマンスが向上しました。
Chrome エンジニアの原健太氏は、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)
以下に、原健太氏が作成したパッチについて詳しく説明します。リンクから 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. S のように 1 つの文字列を割り当ててください。
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 と他のチームメンバーに感謝します。