在Webkit里如何不触发重布局

本文翻译自原文

大部分的Web开发者都知道,一个脚本的执行时间可能更多的花在了DOM的操作上面而不是这段JS代码的本身。其中一个潜在的高消耗操作就是布局(又称回流):从DOM树构建呈现树(render tree)的过程。越大和复杂的DOM,就可能会带来越高的操作消耗。

保持页面敏捷的一个重要的技术就是把操作DOM的操作都放在一起处理。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Suboptimal, causes layout twice.

var newWidth = aDiv.offsetWidth + 10; // Read

aDiv.style.width = newWidth + 'px'; // Write

var newHeight = aDiv.offsetHeight + 10; // Read

aDiv.style.height = newHeight + 'px'; // Write

// Better, only one layout.

var newWidth = aDiv.offsetWidth + 10; // Read

var newHeight = aDiv.offsetHeight + 10; // Read

aDiv.style.width = newWidth + 'px'; // Write

aDiv.style.height = newHeight + 'px'; // Write

Stoyan Stefanov的 Rendering: repaint, relayout and restyle provides 很好的解释了这个问题。
【翻译请看:前端渲染:重绘,重布局和样式重塑

这通常会留给开发者一个问题:什么触发了布局?我在下面总结了一些属性和方法:

Element

clientHeight, clientLeft, clientTop, clientWidth, focus(), getBoundingClientRect(), getClientRects(), innerText, offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth, outerText, scrollByLines(), scrollByPages(), scrollHeight, scrollIntoView(), scrollIntoViewIfNeeded(), scrollLeft, scrollTop, scrollWidth

Frame, Image

height, width

Range

getBoundingClientRect(), getClientRects()

SVGLocatable

computeCTM(), getBBox()
SVGTextContent
getCharNumAtPosition(), getComputedTextLength(), getEndPositionOfChar(), getExtentOfChar(), getNumberOfChars(), getRotationOfChar(), getStartPositionOfChar(), getSubStringLength(), selectSubString()

SVGUse

instanceRoot

window

getComputedStyle(), scrollBy(), scrollTo(), scrollX, scrollY, webkitConvertPointFromNodeToPage(), webkitConvertPointFromPageToNode()

这个列表可能不完整,但是是一个很好的开始。