First talk about two points
Backflow will certainly cause redrawing, redrawing will not necessarily cause backflow;
Backflow costs more than repainting;
backflow
When some or all of the nodes in the Render Tree need to be rebuilt due to changes in the size, layout, hiding, etc., and their exact positions and sizes in the device viewport are calculated, the process of the browser rerendering is called backflow.
Operations that cause backflow:
- Page rendered for the first time.
- The browser window size changed. Procedure
- The size or position of the element changed.
- Element content changes (the number of words or image size changes).
- Element font size changes.
- Add or removevisiblethe
DOM
Elements. - The activation
CSS
Pseudo-classes (eg::hover
). - Query some properties or call some methods.
Some common properties and methods that cause backflow.
clientWidth
,clientHeight
,clientTop
,clientLeft
offsetWidth
,offsetHeight
,offsetTop
,offsetLeft
scrollWidth
,scrollHeight
,scrollTop
,scrollLeft
scrollIntoView()
,scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
redraw
When a change in the style of an element (color, background-color, etc.) in a page does not affect its surrounding or internal layout (size, size, etc.), the browser assigns the new style to the element and redraws it, a process called redraw.
CSS that is easy to redraw
- color
- Border style border-style
- The rounded border – the radius
- Text decoration text-decoration
- Shadow box – shadow
- Outline the outline
- Background background
Pay attention to
Induction reflow
In some cases, such as modifying the elements of style, the browser will not immediately reflow or repaint once, the browser will maintain a queue, put all cause re-flow and re-paint operation in the queue, if the number of tasks in the queue or interval reaches a certain critical value, the browser will turn to perform, a batch, The queue is emptied so that multiple reflows and redraws become one, also known as asynchronous reflow or incremental asynchronous reflow.
Immediately reflow
In some cases, the queue will be forced to empty, i.e. forced backflow, such as the resize window, changing the default font of the page, etc.
When the following properties or methods are accessed, the browser immediately clears the queue and reflow immediately:
clientWidth
,clientHeight
,clientTop
,clientLeft
offsetWidth
,offsetHeight
,offsetTop
,offsetLeft
scrollWidth
,scrollHeight
,scrollTop
,scrollLeft
scrollIntoView()
,scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
Css3 does not require backflow and redraw:
- Transform // Apply 2D or 3D transformations to elements. This property allows you to rotate, scale, move, or tilt elements
- Opacity // Sets the opacity level of the element
- Filter // defines elements (usually) visual effects (e.g. Blur and saturation)
- Will-change // Notify the browser in advance of what we want to animate the element so that the browser can prepare appropriate optimization Settings in advance
Browser drawing DOM
1. Obtain the DOM and divide it into multiple layers; 2. Draw each layer into a separate bitmap; 3.
Typically, the browser will draw the contents of a layer into a bitmap and then upload it to the GPU as a texture. As long as the contents of the layer do not change, there is no need to repaint. The browser will recomposite the contents to form a new frame.
The transform does not redraw because the transform is a composite property. When you animate a composite property, a composite layer is created. This allows animation elements to be rendered in a separate layer. When the content of the element has not changed, there is no need to redraw it. The browser creates the animation frame by recomposing it.
Optimized reflux reduction
There is no change in orientation, only a fading
Try to set the element to visibility because display: None causes backflow and visibility only causes redraw.
Avoid the use oftable
layout
Try not to use a table layout. If there is no fixed width and the width of a table column is determined by the widest column, it is likely that the last row will be wider than the previous column width, causing an overall backflow and causing the table to need multiple computations to determine the attributes of its nodes in the render tree, often taking three times as long as the equivalent element.
For complex animation effects, use absolute positioning to keep them out of the document flow
For complex animation effects, which often cause backflow redrawing, try to set elements to absolute or fixed, so that they are removed from the document stream. When operating on the location attribute of an element, only this element will be backflowed, otherwise it is easy to cause frequent backflows of the parent element and subsequent elements.
Merge style changes
Reduce the amount of backflow. If multiple CSS properties are being manipulated on a node, and each one causes backflow, it is better to rewrite the style property at once, or define the style list as class and change the class property at once (rather than using JS to change each style individually).
Batch operation DOM
Special handling is required to reduce backflow when multiple operations are performed on the DOM. Multiple operations on an element after leaving the standard flow do not trigger backflow. When the operation is complete, the element is put back into the standard stream.
There are three types of operations that deviate from the standard flow:
- Hide elements (display: None, only causes two reflow and redraw)
- Using document fragments (createDocumentFragment: Create a virtual documentFragment node)
- Copy the node
Example: The following multiple operations on the DOM node trigger backflow each time
Var data = [{id: 1, name: "1" goods,}, {id: 2, name: "1" goods,}, {id: 3, name: "1" goods,}, {id: 4, name: "1" goods,}, / / assumptions behind many]; var oUl = document.querySelector("ul"); for(var i=0; i<data.length; i++){ var oLi = document.createElement("li"); oLi.innerText = data[i].name; oUl.appendChild(oLi); }Copy the code
In this way, each operation to add a LI to ul triggers backflow each time.
Method 1: Hide the UL, add a node to the UL, and then display the UL
oUl.style.display = 'none'; for(var i=0; i<data.length; i++){ var oLi = document.createElement("li"); oLi.innerText = data[i].name; oUl.appendChild(oLi); } oUl.style.display = 'block';Copy the code
At this point, backflow is triggered twice when ul is hidden and ul is shown, and no backflow is triggered when each LI is added to ul.
Method 2: Create a document shard, put all li in the document shard first, and then put the document shard in ul
var fragment = document.createDocumentFragment(); for(var i=0; i<data.length; i++){ var oLi = document.createElement("li"); oLi.innerText = data[i].name; fragment.appendChild(oLi); } oUl.appendChild(fragment);Copy the code
DocumentFragment represents a minimal document object that has no parent file. The biggest difference from Document is that DocumentFragment is not part of the real DOM tree, and changes to it do not trigger the DOM tree (re-rendering) or cause performance issues.
The use of the document. CreateDocumentFragment method or constructor to create an empty DocumentFragment.
detailed
Method 3: Make a copy of ul, put all li in the copy, and replace ul with a copy (deep copy) when all li are in the copy.
var newUL = oUl.cloneNode(true); for(var i=0; i<data.length; i++){ var oLi = document.createElement("li"); oLi.innerText = data[i].name; newUL.appendChild(oLi); } oUl.parentElement.replaceChild(newUl, oUl);Copy the code
Pay attention to
CloneNode () stands for shallow copy – the element in the tag, the event is not copied. CloneNode (true) stands for deep copy – copying exactly what’s in the real node
Avoid triggering layouts more than once
Retrieves an element’s scrollTop, scrollLeft, scrollWidth, offsetTop, offsetLeft, offsetWidth, offsetHeight and other attributes. So if you’re going to do it multiple times, you might want to cache it.
Back to the top operation as follows:
goBack.onclick = function(){ setInterval(function(){ var t = document.documentElement.scrollTop || document.body.scrollTop; t += 10; document.documentElement.scrollTop = document.body.scrollTop = t; }}, 20)Copy the code
Every 20 milliseconds, the scrolling distance is reacquired, and each time a backflow is triggered. The code is optimized as follows:
goBack.onclick = function(){ var t = document.documentElement.scrollTop || document.body.scrollTop; setInterval(function(){ t += 10; document.documentElement.scrollTop = document.body.scrollTop = t; }}, 20)Copy the code
Get it only once, increasing the number each time to avoid getting the scrolling distance each time.