1. Browser rendering process
Information in performance
The browser takes a bunch of text, parses all the tags to create a tree, which is the DOM, the document model, and then adds styles to the tree based on the tags, which is the DOM tree -> CSSOM tree
Finally, the dom and csSOM trees are merged into the Render tree. If the render tree is really needed, i.e. span is display: None, then the render tree will delete the element, and Visiblity: Hidden will still be drawn because the DOM is there but it is not displayed
Now look at the render path
1. Javascript: In fact, not just JS, it refers to all operations that can cause visual changes, such as JS manipulating dom, or executing CSS animations, etc
2. Style: The first step is a visual change, the browser needs to re-calculate the style, calculate the correct properties so that it will have the correct visual effect later
E.g. < 1 > We want to draw elements on the page according to our style, but we need to know the location and size of the elements. That’s what layout does.
4. Paint: Actually paint things onto the page
5.com Composite: Composite, we have multiple layers, draw different things on different layers and finally composite one layer
2. Layout and drawing
These two steps are very performance-intensive, and it would be slow to go through these five steps every time a visual change is triggered. The browser optimizes these two steps to not trigger layout and drawing, i.e. some property changes do not trigger these two steps
Only trigger height changes, offset these geometric changes will trigger the layout of this step (such as herght=xx), other such as color changes will not trigger the layout, directly redraw
What attributes don’t trigger a redraw? Some animations can be recomposed using the GPU without causing redrawing
Operations that affect reflow (the first rendering of the page is called layout, and subsequent changes to properties are generally called reflow) :
1. Add and remove elements (element position changes below)
2.display:none
3. Move the position of elements
4. OffetLeft left
5. Change the browser size and font size
6. Operation styles
Avoid layout thrashing and force backflow
Solution;
Avoid backflow: If we change offestLeft to trigger backflow, we can change it to Tranform to move the position. This animation does not rewind backflow and redraw, it only triggers composition
Separation, speaking, reading and writing, after all, sometimes we have to position for operation, we can be read in bulk, and then write should not be read immediately, it will trigger forced to read the latest position last backflow, the browser will originally batch update back, if you read in this position, then the browser will force this time will trigger the backflow.
3. Fastdom: Batch read and write dom
When you put it in a packaged function, you can batch read and then batch write
4. Compound threads and layers
The page is split into many layers, so when properties change, only one layer will be affected, which can be easily modified to reduce the impact.
Analyze the effects of each element and extract the effects into a separate layer so that they can be modified together on another layer
Devtool shows layers to see layers
Perform layer composition operations: transfrom and opacity without redrawing or backflow
With these CSS animations we can extract a separate layer for this element, so that when they change they don’t trigger a backflow redraw, they only trigger a composition, extracting efficiency
If not, the browser will split the layer itself based on the element’s direct dependencies
5. Reduce repainting
So I’m going to do this and I’m going to highlight the green and I’m going to know which elements are being redrawn
We just set the transform and that will still cause a redraw because the element is not in a separate layer, and that will still cause backflow and redraw
We’ll add willchange:’transform’ to the property so that the browser knows to extract a separate layer, and this one didn’t have a separate layer before, and it’s usually this CSS animation that makes it necessary to do a separate layer
6. High frequency time processing function anti-shake
If the high frequency exceeds the number of frames, such as scroll, it will trigger more than once in a frame, so there is no need to handle it more than once
window.addEventListener('pointermove'.(e) = >{
let pos = e.clientX
changeWidth(pos)
console.log('e',e);
})
Copy the code
For example, mouse movement events, in this case n times per frame, now let’s look at the lifetime of a frame
There is an event that triggers a visual change, one frame at a time, which triggers rAf before page layout and drawing, so we use this function to process our function before drawing
FPS is how many frames per second so 60 FPS is 60 frames per second
window.addEventListener('pointermove'.(e) = >{
let pos = e.clientX
window.requestAnimationFrame(() = >{
changeWidth(pos)
})
console.log('e',e);
})
Copy the code
So that adds multiple fires within a frame and we’re only going to do it once because requestAnimationFrame is going to do it once
But it doesn’t make sense for us to keep firing pointermove in a frame and just do it once so we’re going to have to do anti-shake which is do pointermove once in a frame
let ticking = false
window.addEventListener('pointermove'.(e) = >{
let pos = e.clientX
if(ticking) return
ticking = true
window.requestAnimationFrame(() = >{
changeWidth(pos)
ticking=false
})
console.log('e',e);
})
Copy the code
As long as there is a requestAnimationFrame executing, we simply return without calling requestAnimationFrame
React Time scheduling implementation
Achieve requestIdleCallback with rAf. Ric is after redrawing and rAf is before layout. We calculate RIC time according to rAf.