Open ajccom opened 4 years ago
在javascript调用以下属性或方法时,将会触发浏览器同步计算样式和布局。这被称为重排(reflow/layout thrashing),也是常见的性能瓶颈。
window.getComputedStyle() 通常会导致样式的重新计算。
此外,当满足下面任何一种情况时,window.getComputedStyle()都会导致重排:
元素在shadow tree(影子树)中
使用媒体查询(viewport相关的一种)。特别是查询下面的任何一个媒体属性时:
获取下列属性:
如何避免重排呢?下列提供一些解决方法:
以上数据是通过读取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没有很好的数据支持,但是应该大致相符,因为这些返回值内容都已由标准所限制。结果的区别可能就在于优化方法的不同。
强制布局(以及样式的重新计算):UpdateStyleAndLayoutIgnorePendingStylesheets
- Chromium Code Search
强制重新计算样式:UpdateStyleAndLayoutTreeIgnorePendingStylesheets
- Chromium Code Search
CSS Triggers是一个很好的资源网站,它提供了关于设置或者改变一个CSS值时,会导致浏览器生命周期中进行了什么操作的信息。上面列表中都是关于JavaScript中什么操作引起浏览器同步触发紫色(重排)/绿色(重绘)/深绿色(混合)的。
What forces layout / reflow
All of the below properties or methods, when requested/called in JavaScript, will trigger the browser to synchronously calculate the style and layout*. This is also called reflow or layout thrashing, and is common performance bottleneck.
Element
Box metrics
elem.offsetLeft
,elem.offsetTop
,elem.offsetWidth
,elem.offsetHeight
,elem.offsetParent
elem.clientLeft
,elem.clientTop
,elem.clientWidth
,elem.clientHeight
elem.getClientRects()
,elem.getBoundingClientRect()
Scroll stuff
elem.scrollBy()
,elem.scrollTo()
elem.scrollIntoView()
,elem.scrollIntoViewIfNeeded()
elem.scrollWidth
,elem.scrollHeight
elem.scrollLeft
,elem.scrollTop
also, setting themFocus
elem.focus()
can trigger a double forced layout (source&l=2923)Also…
elem.computedRole
,elem.computedName
elem.innerText
(source&l=3440))getComputedStyle
window.getComputedStyle()
will typically force style recalcwindow.getComputedStyle()
will force layout, as well, if any of the following is true: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
, or shorthand] only if the margin is fixed.padding
[-top
,-right
,-bottom
,-left
, or shorthand] only if the padding is fixed.transform
,transform-origin
,perspective-origin
translate
,rotate
,scale
grid
,grid-template
,grid-template-columns
,grid-template-rows
perspective-origin
motion-path
,motion-offset
,motion-rotation
,x
,y
,rx
,ry
window
window.scrollX
,window.scrollY
window.innerHeight
,window.innerWidth
window.getMatchedCSSRules()
only forces styleForms
inputElem.focus()
inputElem.select()
,textareaElem.select()
Mouse events
mouseEvt.layerX
,mouseEvt.layerY
,mouseEvt.offsetX
,mouseEvt.offsetY
(source)document
doc.scrollingElement
only forces styleRange
range.getClientRects()
,range.getBoundingClientRect()
SVG
contenteditable
*Appendix
More on forced layout
section below covers everything in more detail, but the short version is:for
loops that force layout & change the DOM are the worst, avoid them.rAF
, scroll handler, etc), when the numbers are still identical to the last time layout was done.Cross-browser
updateLayoutIgnorePendingStylesheets
- GitHub search - WebKit/WebKitFrameNeedsReflow
- mozilla-central searchBrowsing the Chromium source:
UpdateStyleAndLayoutIgnorePendingStylesheets
- Chromium Code SearchUpdateStyleAndLayoutTreeIgnorePendingStylesheets
- Chromium Code SearchCSS Triggers
CSS Triggers is a related resource and all about what operations are required to happen in the browser lifecycle as a result of setting/changing a given CSS value. It's a great resource. The above list, however, are all about what forces the purple/green/darkgreen circles synchronously from JavaScript.
More on forced layout
Updated slightly Feb 2018. Codesearch links and a few changes to relevant element properties.
来源:https://gist.githubusercontent.com/paulirish/5d52fb081b3570c81e3a/raw/05d5c8aeda72a56ddb1156a08741f138fc11bc09/what-forces-layout.md