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.
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
also, setting them
elem.focus()
can trigger a double forced layout (source)
elem.computedRole
,elem.computedName
elem.innerText
(source)
window.getComputedStyle()
will typically force style recalc (source)
window.getComputedStyle()
will force layout, as well, if any of the following is true:
- The element is in a shadow tree
- There are media queries (viewport-related ones). Specifically, one of the following: (source)
min-width
,min-height
,max-width
,max-height
,width
,height
aspect-ratio
,min-aspect-ratio
,max-aspect-ratio
device-pixel-ratio
,resolution
,orientation
- The property requested is one of the following: (source)
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
webkit-filter
,backdrop-filter
motion-path
,motion-offset
,motion-rotation
x
,y
,rx
,ry
window.scrollX
,window.scrollY
window.innerHeight
,window.innerWidth
window.getMatchedCSSRules()
only forces style
inputElem.focus()
inputElem.select()
,textareaElem.select()
(source)
mouseEvt.layerX
,mouseEvt.layerY
,mouseEvt.offsetX
,mouseEvt.offsetY
(source)
doc.scrollingElement
only forces style
range.getClientRects()
,range.getBoundingClientRect()
- Quite a lot; haven't made an exhaustive list , but Tony Gentilcore's 2011 Layout Triggering List pointed to a few.
- Lots & lots of stuff, …including copying an image to clipboard (source)
- If layout is forced, style must be recalculated first. So forced layout triggers both operations. Their costs are very dependent on the content/situation, but typically both operations are similar in cost.
- The above data was built by reading the Blink source, so it's true for Chrome, Opera, and most android browsers.
- Tony Gentilcore's Layout Triggering List was for 2011 WebKit and generally aligns with the above.
- Modern WebKit's instances of forced layout are mostly consistent:
updateLayoutIgnorePendingStylesheets
- GitHub search - WebKit/WebKit - Gecko's reflow appears to be requested via FrameNeedsReflow. Results:
FrameNeedsReflow
- mozilla-central search - No concrete data on Edge/IE, but it should fall roughly in line, as the return values for these properties are spec'd. What would differ is the amount of clever optimization.
- forced layout (and style recalc):
updateLayoutIgnorePendingStylesheets
- Chromium Code Search - forced style recalc:
updateLayoutTree
- Chromium Code Search
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.
- 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