Reflow and Repaint

Refer to the blog

Page generation process

Here is a process
Text interpretation
  1. The HTML parser parses HTML into a DOM tree

  2. The CSS parser parses the CSS into a CSSOM tree

  3. Combine two trees to generate a Render Tree, a process called Attachment

  4. The browser “draws” all the nodes of the render tree on the screen based on the layout

  5. The layout is then drawn on the screen to show the entire page

  6. The fourth and fifth steps are the most time-consuming and together they are often referred to as rendering

Rearrangement (reflow)

concept

  • When DOM changes affect the geometry of an element (its position and size), the browser needs to recalculate the element’s geometry and place it in the correct position in the interface, a process called rearrangement.
  • Simply regenerating the layout, rearranging the elements.

What happens when you rearrange?

  • Page initial rendering, which is the most expensive rearrangement

  • Add and delete visible DOM elements

  • Change element position

  • Change element size: Total element size = width and height (content fill) + margin + border + margin

  • Change the content of the element: text number, image size, etc

  • Change the element font size

  • Change the browser window size: resize when the event occurs

  • Enable CSS pseudo-classes

  • Add CSS pseudo-elements

  • Set the value of the style property. Each setting triggers a reflow

  • Query some properties or call some calculation methods: OffsetWidth, offsetHeight, etc. In addition, when we call getComputedStyle method, or currentStyle in IE, it will also trigger rearrangement, the principle is the same, both for “real-time” and “accuracy”.

  • It is common to cause rearrangements of properties and methods
    width height margin padding
    display border-width border position
    overflow font-size vertical-align min-height
    clientWidth clientHeight clientTop clientLeft
    offsetWudth offsetHeight offsetTop offsetLeft
    scrollWidth scrollHeight scrollTop scrollLeft
    scrollIntoView() scrollTo() getComputedStyle()
    getBoundingClientRect() scrollIntoViewIfNeeded()

Rearrange the scope of influence

Global scope (avoid)
  • Relayout the entire render tree, starting with the root node HTML.
Local scope
  • Rearrange a part of the render tree or a render object
  • Finalizing the geometry of a DOM element and triggering a rearrangement inside the element will only re-render the elements inside the element, not the outside world

Repaint

concept

  • The process of redrawing the appearance of an element when its appearance is changed without changing its layout.

When does redrawing happen?

  • Properties:
    color border-style visibility background
    text-decoration background-image background-position background-repeat
    outline-color outline outline-style border-radius
    outline-width box-shadow background-size

Rearrange and redraw

  • Both of them affect performance, but rearrangement is a lot of work than drawing, which will make us pay a high performance price

  • Redrawing does not necessarily lead to rearrangement, rearrangement does lead to redrawing

    • Redrawing simply changes the appearance of elements and does not cause the layout of the page to be regenerated

    • When the browser completes the rearrangement, the parts affected by the rearrangement will be redrawn.

Optimization scheme

Reduce the rearrangement range

  • Organize the HTML structure in a local layout with minimal impact on the scope of the rearrangement (BFC)
  • Do not use the table layout, it is possible that a small change will cause the entire table to be rearranged. If you have to use a table, you can set table-layout: Auto; Or table-layout: Fixed renders the table line by line, which is also used to limit the scope of reflow.

Reduce rearrangement times

1. Style set changes
  • It is wise and maintainable for a page to change the class name rather than the style.

  • Batch changes using style.csstext or classname

    • document.getElementById("d1").style.cssText = "color:red; font-size:13px;" ; document.getElementById("d1").classList.replace=('previousClassname','newClassname')Copy the code
2. Separate read and write operations (avoid forced refresh)
  • Multiple reads (or writes) of the DOM should be placed together. Do not add a write operation between two read operations.

    • // bad forces the refresh to trigger four reorders + redraw div.style.left = div.offsetLeft + 1 + 'px'; div.style.top = div.offsetTop + 1 + 'px'; div.style.right = div.offsetRight + 1 + 'px'; div.style.bottom = div.offsetBottom + 1 + 'px'; Var curLeft = div.offsetLeft; var curTop = div.offsetTop; var curRight = div.offsetRight; var curBottom = div.offsetBottom; div.style.left = curLeft + 1 + 'px'; div.style.top = curTop + 1 + 'px'; div.style.right = curRight + 1 + 'px'; div.style.bottom = curBottom + 1 + 'px';Copy the code
Why only one rearrangement is triggered after read/write separation
  • This is thanks to the browser’s render queue mechanism

  • When we modify the geometry of an element, causing the browser to trigger a rearrangement or redraw. It puts the action into the render queue, and when the number of actions in the queue reaches a certain number of times, the browser executes them in batches.

    • div.style.left = '10px'; div.style.top = '10px'; div.style.width = '20px'; div.style.height = '20px'; Console. log(div.offsetleft); // On the first console, when the div. OffsetLeft key style is involved, the browser immediately performs the task of rendering the queue, emptying the render queue for the previous four writes. // Since there may be operations that affect these values in the queue (i.e. the console.log operation prints the latest div.offsetLeft value), the browser immediately reorders and redraws to give us the most accurate values, so the queue is empty. // Note: any operation involving a key attribute, the browser will immediately perform the task of rendering the queue, even if the value is not related to the value you modified during the operation. console.log(div.offsetTop); console.log(div.offsetWidth); console.log(div.offsetHeight); // The rest of the console, since the render queue is empty, does not trigger reordering, just fetching values.Copy the code
    • An operation request to force a queue refresh

      • offsetTop, offsetLeft, offsetWidth, offsetHeight scrollTop, scrollLeft, scrollWidth, scrollHeight clientTop, ClientLeft, clientWidth, clientHeight getComputedStyle(), or IE’s currentStyle
3. The DOM element to be modified is operated offline
1. Using display: none
  • Once we set the elementdisplay:noneWhen (only one rearrangement redraw), the element will no longer exist in the render tree, effectively “removing” it from the page, and our subsequent actions will not trigger rearrangement and redraw, after adding enough changes to passdisplayProperty display (another rearrangement redraw), which triggers only two rearrangements even with a large number of changes.
2. Create fragments
  • throughdocumentFragmentTo create adomShard, batch operation on itdom, and then add to the document, which triggers only one rearrangement.
3. Copy the node
  • Copy cloneNode(deep), work on the copy, and replace replaceChild(newNode,oldNode) with it!
4. Get out of the document stream
  • Using absolute positioning makes that element a separate element in the render treebodyA child element of, the rearrangement cost is relatively small, will not cause too much impact on other nodes. When you place this element on these nodes, some other nodes in the region may need to be redrawn, but not rearranged.
5. Optimize the animation
  • You can apply complex animation effects topositionProperties forabsolutefixedThat has less impact on other elements.
  • Animations should also sacrifice some smoothness in exchange for speed: for example, an animation that moves in pixels is smoothest, but layouts are too frequent and CPU intensive, rather than moving in pixels of 3