In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article focuses on "how to master browser reflow and redrawing". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "how to master browser reflow and redraw"!
Rendering process of the browser
This article first from the browser rendering process to explain the redrawing of reflow from beginning to end, if you want to directly see how to reduce reflow and redraw, optimize performance, you can skip to the back. (this rendering process is from MDN)
Browser render proc
Add description
From the figure above, we can see that the browser rendering process is as follows:
Parse HTML, generate DOM tree, parse CSS, generate CSSOM tree
Combine DOM tree with CSSOM tree to generate render tree (Render Tree)
Layout (reflux): reflow (Layout) according to the generated render tree to get the geometric information (location, size) of the node.
Painting (redraw): get the absolute pixels of the node according to the geometric information obtained by the render tree and reflux
Display: send pixels to GPU and display them on the page. (there is actually a lot of content in this step, such as merging multiple composite layers into the same layer in GPU and displaying it on the page. The principle of css3 hardware acceleration is to create a new composite layer, which we will not expand here, but will write a blog later.)
The rendering process looks simple, so let's take a closer look at what is done at each step.
Generate render Tr
Render tree construction
In order to build the render tree, the browser mainly completes the following tasks:
Iterate through each visible node starting from the root node of the DOM tree.
For each visible node, find the corresponding rules in the CSSOM tree and apply them.
Each visible node and its corresponding style are combined to generate a render tree.
In the * step, now that we're talking about traversing visible nodes, we need to know which nodes are invisible. Invisible nodes include:
Some nodes that do not render output, such as script, meta, link, and so on.
Some nodes that are hidden through css. Like display:none. Note that nodes hidden with visibility and opacity are still displayed on the render tree. Only display:none nodes do not appear on the render tree.
From the above example, we can see that the style of the span tag has a display:none, so it doesn't end up on the render tree.
Note: the render tree contains only visible nodes
Reflux
Earlier, by constructing the render tree, we combined the visible DOM nodes and their corresponding styles, but we also needed to calculate their exact location and size in the device viewport (viewport), which is called backflow.
To find out the exact size and location of each object on the site, the browser starts traversing from the root node of the render tree, which can be represented by the following example:
Critial Path: Hello world! Hello world!
We can see that * div sets the display size of the node to 50% of the viewport width, and the second div sets its size to 50% of the parent node. In the reflux stage, we need to convert the viewport to the actual pixel value according to the specific width of the viewport. (as shown below)
Reflux
Redraw
Finally, by constructing the render tree and the reflux phase, we know which nodes are visible, as well as the style and specific geometric information (location, size) of the visible nodes. then we can convert each node of the render tree to the actual pixel on the screen, which is called redrawing the node.
Now that we know the rendering process of the browser, let's discuss when reflow redrawing will occur.
When does redrawing occur?
As we know earlier, the main purpose of reflow is to calculate the location and geometric information of nodes, so when the page layout and geometric information changes, it needs to be reflowed. For example, the following situations:
Add or remove visible DOM elements
The position of the element has changed
The size of the element changes (including outer margin, inner border, border size, height and width, etc.)
The content changes, such as text changes or the picture is replaced by another picture of a different size.
When the page starts to render (this can't be avoided)
The window size of the browser changes (because reflux calculates the position and size of the element based on the size of the viewport)
Note: reflow must trigger redrawing, but redrawing may not necessarily reflow.
Depending on the scope and extent of the changes, the large or small parts of the rendering tree need to be recalculated, and some changes trigger a rearrangement of the entire page, such as when the scroll bar appears or the root node is modified.
Optimization mechanism of browser
Modern browsers are smart, and because each rearrangement consumes additional computation, most browsers optimize the rearrangement process by queuing changes and executing them in batches. The browser puts the modification operation in the queue until a period of time or the operation reaches a threshold before emptying the queue. But! Force queue refresh when you get layout information, such as when you access the following properties or use the following methods:
OffsetTop 、 offsetLeft 、 offsetWidth 、 offsetHeight
ScrollTop 、 scrollLeft 、 scrollWidth 、 scrollHeight
ClientTop 、 clientLeft 、 clientWidth 、 clientHeight
GetComputedStyle ()
GetBoundingClientRect
You can visit this website: https://gist.github.com/pauli...
The above properties and methods all need to return the layout information of * *, so the browser has to empty the queue and trigger reflow redrawing to return the correct value. Therefore, when we modify the style, * avoid using the attributes listed above, they will refresh the rendering queue. If you want to use them, * cache the values.
Reduce backflow and redraw
All right, when it comes to our highlight today, with so much background and theoretical knowledge, let's talk about how to reduce backflow and redrawing.
Minimize redrawing and rearrangement
Because redrawing and rearranging can be expensive, you can reduce the number of times they occur. To reduce the number of occurrences, we can merge multiple changes to DOM and styles, and then dispose of them at once. Consider this example.
Const el = document.getElementById ('test'); el.style.padding =' 5pxrabbit; el.style.borderLeft = '1pxflux; el.style.borderRight =' 2px'
In the example, three style attributes have been modified, each of which affects the geometry of the element, causing reflux. Of course, most modern browsers optimize it, so it only triggers a rearrangement. But if other code accesses the layout information (the layout information that triggers backflow above) in older browsers or during the execution of the above code, it will result in three rearrangements.
Therefore, we can merge all the changes and deal with them in turn, for example, we can take the following ways:
Use cssText
Const el = document.getElementById ('test'); el.style.cssText + =' border-left: 1px; border-right: 2px; padding: 5pxten'
Modify the class of CSS
Const el = document.getElementById ('test'); el.className + =' active'
Modify DOM in batch
When we need to make a series of changes to DOM, we can reduce the number of redrawing times by using the following steps:
Detach an element from the document stream
Modify it many times
Bring the element back to the document.
Steps * * and step 3 of the process may cause reflow, but after step * *, any changes to DOM will not cause reflow redrawing because it is no longer rendering the tree.
There are three ways to get DOM out of the document stream:
Hide elements, apply changes, redisplay
Use document fragments (document fragment) to build a subtree outside of the current DOM, and then copy it back to the document.
Copy the original element to a node that is detached from the document, modify the node, and then replace the original element.
Consider that we are going to execute a piece of code that inserts nodes in bulk:
Function appendDataToElement (appendToElement, data) {let li; for (let I = 0; I)
< data.length; i++) { li = document.createElement('li'); li.textContent = 'text'; appendToElement.appendChild(li); } } const ul = document.getElementById('list'); appendDataToElement(ul, data); 如果我们直接这样执行的话,由于每次循环都会插入一个新的节点,会导致浏览器回流一次。 我们可以使用这三种方式进行优化: 隐藏元素,应用修改,重新显示 这个会在展示和隐藏节点的时候,产生两次回流 function appendDataToElement(appendToElement, data) { let li; for (let i = 0; i < data.length; i++) { li = document.createElement('li'); li.textContent = 'text'; appendToElement.appendChild(li); } } const ul = document.getElementById('list'); ul.style.display = 'none'; appendDataToElement(ul, data); ul.style.display = 'block'; 使用文档片段(document fragment)在当前DOM之外构建一个子树,再把它拷贝回文档 const ul = document.getElementById('list'); const fragment = document.createDocumentFragment(); appendDataToElement(fragment, data); ul.appendChild(fragment); 将原始元素拷贝到一个脱离文档的节点中,修改节点后,再替换原始的元素。 const ul = document.getElementById('list'); const clone = ul.cloneNode(true); appendDataToElement(clone, data); ul[xss_clean].replaceChild(clone, ul); 对于上面这三种情况,我写了一个demo在safari和chrome上测试修改前和修改后的性能。然而实验结果不是很理想。 原因:原因其实上面也说过了,现代浏览器会使用队列来储存多次修改,进行优化,所以对这个优化方案,我们其实不用优先考虑。 避免触发同步布局事件 上文我们说过,当我们访问元素的一些属性的时候,会导致浏览器强制清空队列,进行强制同步布局。举个例子,比如说我们想将一个p标签数组的宽度赋值为一个元素的宽度,我们可能写出这样的代码: function initP() { for (let i = 0; i < paragraphs.length; i++) { paragraphs[i].style.width = box.offsetWidth + 'px'; } } 这段代码看上去是没有什么问题,可是其实会造成很大的性能问题。在每次循环的时候,都读取了box的一个offsetWidth属性值,然后利用它来更新p标签的width属性。这就导致了每一次循环的时候,浏览器都必须先使上一次循环中的样式更新操作生效,才能响应本次循环的样式读取操作。每一次循环都会强制浏览器刷新队列。我们可以优化为: const width = box.offsetWidth; function initP() { for (let i = 0; i < paragraphs.length; i++) { paragraphs[i].style.width = width + 'px'; } } 同样,我也写了个demo来比较两者的性能差异。你可以自己点开这个demo体验下。这个对比的性能差距就比较明显。 对于复杂动画效果,使用绝对定位让其脱离文档流 对于复杂动画效果,由于会经常的引起回流重绘,因此,我们可以使用绝对定位,让它脱离文档流。否则会引起父元素以及后续元素频繁的回流。这个我们就直接上个例子。 打开这个例子后,我们可以打开控制台,控制台上会输出当前的帧数(虽然不准)。 添加描述 从上图中,我们可以看到,帧数一直都没到60。这个时候,只要我们点击一下那个按钮,把这个元素设置为绝对定位,帧数就可以稳定60。 css3硬件加速(GPU加速) 比起考虑如何减少回流重绘,我们更期望的是,根本不要回流重绘。这个时候,css3硬件加速就闪亮登场啦!! 划重点: 1. 使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘 。 2. 对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。 本篇文章只讨论如何使用,暂不考虑其原理,之后有空会另外开篇文章说明。 如何使用 常见的触发硬件加速的css属性: transform opacity filters Will-change 效果 我们可以先看个例子。我通过使用chrome的Performance捕获了动画一段时间里的回流重绘情况,实际结果如下图:Add description
As we can see from the picture, there is no redrawing during the animation. If you are interested, you can also do the experiment yourself.
Highlight
Using css3 hardware acceleration, you can make sure that animations such as transform, opacity and filters do not cause reflow redrawing.
Other properties of animations, such as background-color, can still cause redrawing, but it can still improve the performance of these animations.
Css3 hardware acceleration pit
Of course, any good thing will have a corresponding price, too much. There are still holes in css3 hardware acceleration:
If you use css3 hardware acceleration for too many elements, it will result in a large memory footprint and performance problems.
Rendering fonts in GPU causes anti-aliasing to be invalid. This is because GPU and CPU have different algorithms. So if you don't turn off hardware acceleration at the end of the animation, the font will be blurred.
At this point, I believe you have a deeper understanding of "how to master browser reflow and redrawing". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.