[转] 触发浏览器回流的属性方法一览表
转载自 奇舞周刊 何文力
@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
Windows.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
- Windows
- Windows.scrollX, Windows.scrollY
- Windows.innerHeight, Windows.innerWidth
Windows.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
来源: http://www.jianshu.com/p/ef0559836567