Reflow and redraw of Js

In HTML, each element can be understood as a box. During the browser parsing process, reflow and redrawing will be involved:

  • Reflow (reflow): The layout engine will calculate the size and position of each box on the page according to various styles

  • Redrawing: After calculating the position, size and other attributes of the box model, the browser draws according to the characteristics of each box

The specific browser parsing and rendering mechanism is as follows:

  • Parse HTML, generate DOM tree, parse CSS, generate CSSOM tree

  • Combine DOM tree and CSSOM tree to generate Render Tree

  • Layout (reflow): According to the generated rendering tree, reflow (Layout) is performed to obtain the geometric information (position, size) of the node

  • Painting (redrawing): According to the geometric information obtained by the rendering tree and reflow, the absolute pixel of the node is obtained

  • Display: Send pixels to the GPU and display them on the page

In the initial rendering stage of the page, reflow is inevitably triggered, which can be understood as an element that is blank at the beginning of the page, and new elements are added later to change the page layout

When we  change the geometric size of the modification (such as modifying the width, height or hidden elements of the element, etc.), the browser needs to recalculate the geometric properties of the element, and then draw the calculated DOM result DOM 

When our  DOM modification of the element causes a change in style ( coloror background-color), but does not affect its geometric properties, the browser does not need to recalculate the geometric properties of the element, and directly draws a new style for the element, which only triggers redrawing

2. How to trigger

To reduce the number of reflows and redraws, first understand how reflows and redraws are triggered

Reflow trigger timing

The stage of reflow is mainly to calculate the position and geometric information of nodes, so when the page layout and geometric information change, reflow is required, as follows:

  • Add or remove visible DOM elements
  • The position of the element changes
  • The size of the element changes (including margins, inner borders, border size, height and width, etc.)
  • Content changes, such as text changes or an image is replaced by another image of a different size
  • When the page starts to render (this cannot be avoided)
  • The browser's window size changes (because reflow calculates the position and size of elements based on the size of the viewport)

There are also some operations that are easily overlooked: get the value of some specific attributes

offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

These attributes have one thing in common, that is, they need to be calculated on the fly. Therefore, in order to obtain these values, the browser will also reflow

In addition to getComputedStyle the method, the principle is the same

redraw trigger timing

Triggering a reflow will definitely trigger a redraw

The page can be understood as a blackboard, and there is a small painted flower on the blackboard. Now we want to move this flower from the left to the right, then we need to determine the specific position on the right, draw the shape (reflow), and then paint its original color (redraw)

In addition, there are some other redrawing behaviors:

  • color modification

  • Text Orientation Modification

  • shadow modification

Browser optimization mechanism

Since each rearrangement will cause additional calculation consumption, most browsers will optimize the rearrangement process by queuing modifications and executing them in batches. The browser will put the modification operation into the queue, and the queue will not be emptied until a period of time or the operation reaches a threshold

When you get the operation of layout information, the queue will be forced to refresh, including the methods mentioned above offsetTopwill return the latest data

So the browser has to clear the queue and trigger a reflow repaint to return the correct value

3. How to reduce

We have learned how to trigger reflow and redraw the scene, and the experience of avoiding reflow is given below:

  • If you want to set the style of the element, by changing the class name of the element  class (as far as possible in the innermost layer of the DOM tree)
  • Avoid setting multiple inline styles
  • Applies the animation of the element, using   the value or  value position of the attribute   (as mentioned in the previous example)fixedabsolute
  • Avoid using  table layout, table the size and content of each element in the change will cause the entire  table recalculation
  • For those complex animations, set them  position: fixed/absoluteto make the element out of the document flow as much as possible, so as to reduce the impact on other elements
  • Using css3 hardware acceleration, you can make transform, opacity, and filtersthese animations not cause reflow redrawing
  • Avoid CSS  JavaScript expressions

When using  JavaScript dynamic insertion of multiple nodes, it can be used DocumentFragment. Once created, it can be inserted once. It can avoid multiple rendering performance

But sometimes, we will inevitably reflow or redraw, we can make better use of them:

1. Avoid changing styles, use class names to merge styles:

const container = document.getElementById('container')
container.style.width = '100px'
container.style.height = '200px'
container.style.border = '10px solid red'
container.style.color = 'red'

 Change to:

<style>
    .basic_style {
        width: 100px;
        height: 200px;
        border: 10px solid red;
        color: red;
    }
</style>
<script>
    const container = document.getElementById('container')
    container.classList.add('basic_style')
</script>

The former triggers a rendering tree change every time it is operated separately (new browsers will not),

To trigger a rendering tree change, resulting in the corresponding reflow and redraw process

After merging, it means we send all the changes at once

2. Take the DOM "offline"

const container = document.getElementById('container')
container.style.width = '100px'
container.style.height = '200px'
container.style.border = '10px solid red'
container.style.color = 'red'
...(省略了许多类似的后续操作)

Change to:

let container = document.getElementById('container')
container.style.display = 'none'
container.style.width = '100px'
container.style.height = '200px'
container.style.border = '10px solid red'
container.style.color = 'red'
...(省略了许多类似的后续操作)
container.style.display = 'block'

Some students will ask, if you remove an element and put it back, won't this also trigger an expensive reflow? This is true, but we took it down. No matter how many times I operate this element in the future, the operation cost of each step will be very low. When we only need to do a few DOM operations, the advantages of DOM offline are really not obvious. Once the operation is frequent, the overhead of "removing" and "putting back" will be very worthwhile.

references:

Reflow and Repaint - Nuggets

Guess you like

Origin blog.csdn.net/weixin_45346457/article/details/125759701