Processing flow chart for browser rendering of web pages:
Specific processing steps:
1. The browser parses the obtained HTML code into a DOM tree. Each tag (tag) in HTML is a node in the DOM tree, and the root node is our commonly used document object. The DOM tree contains all HTML tags, including display:none hidden, and elements dynamically added using JS;
2. The browser parses all styles (user-defined css and user agents) into style structures body, styles that the browser cannot recognize will be removed during the parsing process. For example, IE will remove styles starting with -moz, and Firefox will remove styles starting with _;
3. After combining the DOM tree and style structure Build a render tree. The render tree is similar to the DOM tree, but the difference is very big. The render tree can identify styles. Each node of the render tree has its own style, and the render tree does not contain hidden nodes (such as display). :none nodes, as well as head nodes), because these nodes will not be used for rendering and will not affect rendering.
Note: elements hidden by visibility:hidden will still be included in the render tree, because visibility:hidden will affect the layout and occupy space. According to the CSS2 standard, each node in the render tree is called a Box (Box demensions), and the page element is understood to be a box with padding, margins, borders and position.
4. Once the render tree is built, the browser can draw the page based on the render tree.
Redraw
Redraw is a browser behavior triggered by a change in the appearance of an element, such as changing visibility, outline, and background color attributes. The browser will redraw the element based on its new attributes, giving the element a new appearance.
Reflow
Reflow is a more obvious change, which can be understood as the render tree needs to be recalculated. Every page needs to be reflowed at least once, which is when the page loads.
Note: Reflow will definitely cause redraw, but redraw does not necessarily cause reflow.
Trigger reflow
1.Resizing the windown;
2.Changing the font;
3. Adding or removing a stylesheet;
4. Content changes, such as a user typing text in an input box);
5. Activation of css pseudo classes such as :hover (in IE the activation of the pseduo class of a silibing));
6. Manipulating the class attribute;
7. Script manipulating the DOM (a script manipulating the DOM);
8. Calculating offsetWidth and offsetHeight attributes (calculating offsetWidth and offsetHeight);
9. Setting a property of the style attribute.
How to reduce reflow and redraw
1. Change the className directly. If you change the style dynamically, use cssText (consider unoptimized browsers);
// 不好的写法 var left = 1; var top = 1; el.style.left = left + "px"; el.style.top = top + "px";// 比较好的写法 el.className += " className1"; // 比较好的写法 el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
2. Let the operated elements be "offline processed", and update once after processing;
Use DocumentFragment to perform caching operations, triggering a reflow and redraw;
Use the display:none attribute to trigger only two reflows and redraws;
Use cloneNode (true or false) and replaceChild technology to trigger one reflow and redraw.
3. Do not frequently access attributes that will cause the browser to flush the queue. If you are sure you want to cache, use the cache;
// 不好的写法 for(循环) { el.style.left = el.offsetLeft + 5 + "px"; el.style.top = el.offsetTop + 5 + "px"; } // 这样写好点 var left = el.offsetLeft, top = el.offsetTop, s = el.style; for (循环) { left += 10; top += 10; s.left = left + "px"; s.top = top + "px"; }
4. Let the element escape animation Flow, reduce the size of the reflow render tree;
$("#block1").animate({left:50}); $("#block2").animate({marginLeft:50});
5. Change the class at the end of the DOM tree as much as possible (to limit the scope of reflow);
6. Avoid setting multiple layers of inline styles (merge the styles in an external class, resulting in only one reflow);
7. Apply animation effects to elements whose position attribute is absolute or fixed (animation effects are applied On elements whose position attribute is absolute or fixed, they do not affect the layout of other elements, so they will only cause redrawing, rather than a complete reflow. This will be lower);
8. Sacrifice smoothness for speed (Opera also recommends that we trade smoothness for speed, meaning you might want to move an animation 1 pixel at a time, but if this animation and subsequent reflow uses 100% of the CPU, the animation will look It's jumpy because the browser is struggling with update reflows. Animating elements moving 3 pixels at a time may look less smooth on very fast machines, but it won't hit the CPU on slower machines and mobile devices. Medium jitter. );
9. Avoid using table data (tables often require multiple passes before the layout is fully established, because tables are rare and can affect the display of DOM elements that have been entered before them. element. );
10.避免使用css的JavaScript表达式(因为他们每次重新计算文档,或部分文档、回流。正如我们从所有的很多事情看到的:引发回流,它可以每秒产生成千上万次。)。
实例测试一:
测试代码不改变元素的规则,大小,位置。只改变颜色,所以不存在回流,仅测试重绘,代码如下:
<body> <script type="text/javascript"> var s = document.body.style; var computed; if (document.body.currentStyle) { computed = document.body.currentStyle; } else { computed = document.defaultView.getComputedStyle(document.body, ''); } function testOneByOne(){ s.color = 'red';; tmp = computed.backgroundColor; s.color = 'white'; tmp = computed.backgroundImage; s.color = 'green'; tmp = computed.backgroundAttachment; } function testAll() { s.color = 'yellow'; s.color = 'pink'; s.color = 'blue'; tmp = computed.backgroundColor; tmp = computed.backgroundImage; tmp = computed.backgroundAttachment; } </script> color test <br /> <button onclick="testOneByOne()">Test One by One</button> <button onclick="testAll()">Test All</button> </body>
实例测试二:
跟第一次测试的代码很类似,但加上了对layout的改变,为的是测试回流。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1 /DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> </head> <body> <script type="text/javascript"> var s = document.body.style; var computed; if (document.body.currentStyle) { computed = document.body.currentStyle; } else { computed = document.defaultView.getComputedStyle(document.body, ''); } function testOneByOne(){ s.color = 'red'; s.padding = '1px'; tmp = computed.backgroundColor; s.color = 'white'; s.padding = '2px'; tmp = computed.backgroundImage; s.color = 'green'; s.padding = '3px'; tmp = computed.backgroundAttachment; } function testAll() { s.color = 'yellow'; s.padding = '4px'; s.color = 'pink'; s.padding = '5px'; s.color = 'blue'; s.padding = '6px'; tmp = computed.backgroundColor; tmp = computed.backgroundImage; tmp = computed.backgroundAttachment; } </script> color test <br /> <button onclick="testOneByOne()">Test One by One</button> <button onclick="testAll()">Test All</button> </body> </html>
避免回流和重绘的次数可从代码的角度来实现性能优化,因此我们在写代码时应尽量使用上诉方法来减少网页回流和重绘的次数。