(2)Repaint,即重绘。意味着元素发生的改变只是影响了元素的一些外观之类的时候(例如,背景色,边框颜色,文字颜色等),此时只需要应用新样式绘制这个元素就可以了。
回流的成本开销要高于重绘,而且一个节点的回流往往回导致子节点以及同级节点的回流, 所以优化方案中一般都包括,尽量避免回流。
6、什么引起回流1.页面渲染初始化
2.DOM 结构改变,比如删除了某个节点
3.render 树变化,比如减少了 padding
4.窗口 resize
5.最复杂的一种:获取某些属性,引发回流,
很多浏览器会对回流做优化,会等到数量足够时做一次批处理回流,
但是除了 render 树的直接变化,当获取一些属性时,浏览器为了获得正确的值也会触发回流,这样使得浏览器优化无效,包括
回流一定伴随着重绘,重绘却可以单独出现。
优化方案:
(1)减少逐项更改样式,做好一次性更改样式。或者将样式定义为 class,并一次性更新。
(2)避免循环操作 dom,创建一个 documentFragment 或 div,在他上面进行所有的 dom 操作,最后添加到 window.document 中。
(3)避免多次读取 offset 等属性,无法避免就将他们缓存到变量中。
(4)将复杂的元素绝对定位或者固定定位,使他们脱离文档流,否则回流代价很高。
注意:改变字体大小会引起回流。
再看一个例子:
var s = document.body.style; s.padding = "2px"; // 回流+重绘 s.border = "1px solid red"; // 再一次 回流+重绘 s.color = "blue"; // 再一次重绘 s.backgroundColor = "#ccc"; // 再一次 重绘 s.fontSize = "14px"; // 再一次 回流+重绘 // 添加node,再一次 回流+重绘 document.body.appendChild(document.createTextNode('abc!')); 7、简单层和复合层上述中的渲染中止步于绘制,但实际上绘制这一步也没有这么简单,它可以结合复合层和简单层的概念来讲。
简单介绍下:
(1)可以默认只有一个复合层,所有的 DOM 节点都是在这个复合图层下。
(2)如果开启了硬件加速功能,可以将某一个节点变成复合图层。
(3)复合图层之间的绘制互不干扰,直接 GPU 直接控制。
(4)简单图层中,就算是 absolute 等布局,变化时不影响整体回流,但是由于在同一个图层中,仍然会影响绘制的,因此做动画时候性能仍然很低。而且复合层是独立的,所以一般做动画推荐使用硬件加速。
更多参考:
8、Chrome 的调试Chrome 的开发者工具中,Performance 中可以看到详细的渲染过程:
9、资源外链的下载上面介绍了 html 解析,渲染流程。但实际上,在解析 html 时,会遇到一些资源连接,此时就需要进行单独处理了。
简单起见,这里将遇到的静态资源分为一下几大类(未列举所有):
遇到外链的处理
css 样式资源
js 脚本资源
img 图片类资源
以下针对每种情况进行详细说明:
遇到外链的处理
当遇到上述的外链时,会单独开启一个下载线程去下载资源(http1.1 中是每一个资源的下载都要开启一个 http 请求,对应一个 tcp/ip 链接)
遇到 css 样式资源
css 资源处理特点:
(1)css 下载时异步的,不会阻塞浏览器构建 DOM 树;
(2)但是会阻塞渲染,也就是在构建 render 树时,等到 css 下载解析后才进行(与浏览器优化有关,防止 css 规则不断变化,避免重复的构建)
(3)有例外,遇到 media query 声明的 css 是不会阻塞构建 render 树
遇到 js 脚本资源
JS 脚本资源的处理有几个特点:
(1)阻塞浏览器的解析,也就是说发现一个外链脚本时,需等待脚本下载完成并执行后才会继续解析 HTML。