参考博客1:https://blog.csdn.net/sinat_37328421/article/details/54575638
参考博客2:https://blog.csdn.net/yummy_go/article/details/50696328
一、页面渲染的过程
1.解析HTML代码并生成一个 DOM 树。
2.解析CSS文件,顺序为:浏览器默认样式->自定义样式->页面内的样式。
3.生成一个渲染树(render tree)。这个渲染树和DOM树的不同之处在于,它是受样式影响的。它不包括那些不可见的节点。
4.当渲染树生成之后,浏览器就会在屏幕上“画”出所有渲染树中的节点。
二、DOM树和渲染树的区别
DOM+css= Render Tree
render tree (不包含隐藏的节点,比如display:none,还有head节点),因为这些节点不会用于呈现,而且不会影响呈现的。
注意 visibility:hidden隐藏的元素还是会包含到 render tree中的,因为visibility:hidden 会影响布局(layout),会占有空间。
三、重绘和重排
(不管页面发生了重绘还是重排,它们都会影响性能,最可怕的是重排 ,应尽量避免)
1、重排发生的情况
添加或删除可见的DOM元素;
元素位置改变;
元素的尺寸改变(包括:内外边距、边框厚度、宽度、高度等属性的改变);
内容改变;
页面渲染器初始化;
浏览器窗口尺寸改变。
2、重绘发生的情况
重绘发生在元素的可见的外观被改变,但并没有影响到布局的时候。比如,仅修改DOM元素的字体颜色(只有Repaint,因为不需要调整布局)
四、优化方法(减少重排、重绘)
1. 将多次改变样式属性的操作合并成一次操作。
2.将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
3. 在内存中多次操作节点,完成后再添加到文档中去。例如要异步获取表格数据,渲染到页面。可以先取得数据后在内存中构建整个表格的html片段,再一次性添加到文档中去,而不是循环添加每一行。
4. 由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示。这样只在隐藏和显示时触发2次重排。
5. 在需要经常取那些引起浏览器重排的属性值时,要缓存到变量。
(过多触发3d加速,反而会影响性能。)