【转】触发浏览器回流的属性方法一览表
转载自 奇舞周刊 何文力
@TiffanysBear
下列的所有属性、方法,在读取或执行的同时,将会导致浏览器同步地计算样式和布局。这种行为又叫做回流,也是常见的性能瓶颈。
元素类
元素测量
elem.offsetLeft, elem.offsetTop, elem.offsetWidth, elem.offsetHeight, elem.offsetParent
elem.clientLeft, elem.clientTop, elem.clientWidth, elem.clientHeight elem.getClientRects(), elem.getBoundingClientRect()
滚动相关
elem.scrollBy(), elem.scrollTo()
elem.scrollIntoView(), elem.scrollIntoViewIfNeeded()
elem.scrollWidth, elem.scrollHeight
elem.scrollLeft, elem.scrollTop
除了读取,设置也会触发
聚焦
elem.focus()
会触发两次强制布局
其他
elem.computedRole, elem.computedName
elem.innerText
getComputedStyle
window.getComputedStyle()
调用通常会导致样式的重新计算,并且,当满足下列条件时,会触发强制布局:
元素属于一颗影子树中
出现下列任意一个媒体查询时:
min-width, min-height, max-width, max-height, width, height
aspect-ratio, min-aspect-ratio, max-aspect-ratio
device-pixel-ratio, resolution, orientation , min-device-pixel-ratio, max-device-pixel-ratio
所获取的属性是下列之一时:
height, width
top, right, bottom, left
margin [-top, -right, -bottom, -left, 或简写形式]
仅在数值是定值时
padding [-top, -right, -bottom, -left, 或简写形式]
仅在数值是定值时
transform, transform-origin, perspective-origin
translate, rotate, scale
grid, grid-template, grid-template-columns, grid-template-rows
perspective-origin
window
window.scrollX, window.scrollY
window.innerHeight, window.innerWidth
window.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
网友评论