DOM 大幅提高 - WebKit's innerHTML 的速度快上 240%

我們很高興看到某些常見的 DOM 作業速度大幅提升。這些變更是在 WebKit 層級進行,可提升 Safari (JavaScriptCore) 和 Chrome (V8) 的效能。

Chrome 工程師 Kentaro Hara 在 WebKit 中進行了七項程式碼最佳化,以下是結果,可瞭解 JavaScript DOM 存取速度提升了多少:

DOM 效能提升摘要

以下是 Kentaro Hara 對他所做的部分修補程式進行詳細說明。這些連結會連往 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 的新行為:分配一個字串,例如 S。1. 將每個標記的字串連結至 S,逐步剖析 DOM 樹狀結構。1. 以 innerHTML 的形式傳回 S。

簡而言之,這個修補程式會建立一個字串,然後逐漸附加字串,而非建立大量字串再連結。

在 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),以免轉換作業執行多次。

測試如何運作?

可用來測量資源存取時間。在 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;
}

好消息是,Kentaro Hara 認為其他重要的 DOM 屬性和方法,也有機會進一步改善效能。

來吧!

感謝 Haraken 和其他團隊成員。