【转】触发浏览器回流的属性方法一览表
转载自 奇舞周刊 何文力
@TiffanysBear
下列的所有属性、方法,在读取或执行的同时,将会导致浏览器同步地计算样式和布局。这种行为又叫做回流,也是常见的性能瓶颈。
元素类
元素测量
elem.offsetLeft, elem.offsetTop, elem.offsetWidth, elem.offsetHeight, elem.offsetParentelem.clientLeft, elem.clientTop, elem.clientWidth, elem.clientHeight
elem.getClientRects(), elem.getBoundingClientRect()
滚动相关
elem.scrollBy(), elem.scrollTo()elem.scrollIntoView(), elem.scrollIntoViewIfNeeded()elem.scrollWidth, elem.scrollHeightelem.scrollLeft, elem.scrollTop 除了读取,设置也会触发
聚焦
elem.focus() 会触发两次强制布局
其他
elem.computedRole, elem.computedNameelem.innerTextgetComputedStyle
window.getComputedStyle() 调用通常会导致样式的重新计算,并且,当满足下列条件时,会触发强制布局:
元素属于一颗影子树中
出现下列任意一个媒体查询时:min-width, min-height, max-width, max-height, width, heightaspect-ratio, min-aspect-ratio, max-aspect-ratiodevice-pixel-ratio, resolution, orientation , min-device-pixel-ratio, max-device-pixel-ratio
所获取的属性是下列之一时:
height, widthtop, right, bottom, leftmargin [-top, -right, -bottom, -left, 或简写形式] 仅在数值是定值时padding [-top, -right, -bottom, -left, 或简写形式] 仅在数值是定值时transform, transform-origin, perspective-origintranslate, rotate, scalegrid, grid-template, grid-template-columns, grid-template-rowsperspective-originwindow
window.scrollX, window.scrollYwindow.innerHeight, window.innerWidthwindow.getMatchedCSSRules() 仅会导致样式重新计算
表单:
inputElem.focus()inputElem.select(), textareaElem.select()
鼠标事件:
mouseEvt.layerX, mouseEvt.layerY, mouseEvt.offsetX, mouseEvt.offsetY
document
doc.scrollingElement 仅会导致样式重新计算
Range:
range.getClientRects(), range.getBoundingClientRect()
SVG
可以参见 Tony Gentilcore’s 2011 Layout Triggering List
contenteditable
很多行为都会触发,包括复制粘贴图像进去
附录
在文档发生改变或布局、样式失效时会导致回流的消耗。通常,这是因为DOM发生了改变(类的修改,节点的增加、删除,甚至是添加一个伪类如 :focus);
如果需要强制布局,样式首先会被重新计算。所以强制布局会导致这两种操作的发生。它们所消耗的性能取决于当时的内容或者情况,但通常来说两者所消耗的性能都是相似的;
一些简单的解决办法:
- 避免在 for 循环中强制布局以及更改DOM
- 使用开发工具分析产生影响的代码
- 批量读写DOM(使用FastDOM或者其他的虚拟DOM实现)
上述数据在各个浏览器中的表现:
上面的数据是通过阅读 Blink 源码所得,对于 Chrome, Opera 以及大多数安卓浏览器来说是可用的
Tony Gentilcore’s Layout Triggering List 的文章针对遇 2011 年的 WebKit 并且与上述数据基本一致现代 WebKit 中出现强制布局的情况是基本上一致的 updateLayoutIgnorePendingStylesheets - GitHub search - WebKit/WebKit
Gecko 内核的回流请求通过 FrameNeedsReflow 进行 FrameNeedsReflow - mozilla-central search
对于 Edge / IE 没有很好的数据支持,但是基本上都是应该一致的,因为这些返回值内容都已经由标准所限制。对于最终结果,可能由于优化方法不同而不同。
Chromium 源码
- 强制布局(以及样式的重新计算)UpdateStyleAndLayoutIgnorePendingStylesheets - Chromium Code Search
- 强制样式重新计算UpdateStyleAndLayoutTreeIgnorePendingStylesheets - Chromium Code Search
CSS Triggers
CSS Triggers 提供了一个很好的资源,里面记载了关于设置或者改变一个CSS数值时,浏览器内需要做什么操作的信息。
更多关于强制布局的信息
- Avoiding layout thrashing — Web Fundamentals
- Fixing Layout thrashing in the real world | Matt Andrews
- Timeline demo: Diagnosing forced synchronous layouts - Google Chrome
- Preventing ‘layout thrashing’ | Wilson Page
- wilsonpage/fastdom
- Rendering: repaint, reflow/relayout, restyle / Stoyan
- We spent a week making Trello boards load extremely fast. Here’s how we did it. - Fog Creek Blog
- Minimizing browser reflow | PageSpeed Insights | Google Developers
- Optimizing Web Content in UIWebViews and Websites on iOS
- Accelerated Rendering in Chrome
- web performance for the curious
- Jank Free