DOM 性能大幅提升 - WebKit 的 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 中的新行为: 1. 请分配一个字符串,说出“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%

在 WebKit 中,CSS 属性字符串(例如 .fontWeight.backgroundColor)会转换为整数 ID。这种转化非常耗费资源。该补丁会将转换结果缓存在映射中(即属性字符串 => 整数 ID),因此不会执行多次转换。

这些测试是如何运作的?

它们会衡量访问媒体资源的时间。如果使用 innerHTMLbugs.webkit.org/show_bug.cgi?id=81214 中的性能测试),该测试仅测量运行以下代码的时间:

for (var i = 0; i < 1000000; i++)
    document.body.innerHTML;

性能测试使用的是从 HTML 规范中复制的大型正文。

同样,CSS property-accesses 测试会测量以下代码的时间:

var spanStyle = span.style;
for (var i = 0; i < 1000000; i++) {
    spanStyle.invalidFontWeight;
    spanStyle.invalidColor;
    spanStyle.invalidBackgroundColor;
    spanStyle.invalidDisplay;
}

但好消息是,Kentaro Hara 认为其他重要的 DOM 属性和方法将能实现更多性能改进。

来吧!

祝好 Haraken 和团队的其他成员。