学习渡一课程、参考 必须明白的浏览器渲染机制 - 掘金
HTML解析
布局
分层
绘制
分块
光栅化
画
解析html会生成一个 dom树和cssom树
document.styleSheets 可以看到cssom树
在渲染的过程中,遇到一个script标记时,就会停止渲染,去请求脚本文件并执行脚本文件,因为浏览器渲染和 JS 执行共用一个线程,而且这里必须是单线程操作,多线程会产生渲染 DOM 冲突。JavaScript的加载、解析与执行会严重阻塞DOM的构建。只有等到脚本文件执行完毕,才会去继续构建DOM。
js不单会阻塞DOM构建,还会导致CSSOM也阻塞DOM的构建,如果JavaScript脚本还操作了CSSOM,而正好这个CSSOM还没有下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建,然后再执行JavaScript,最后在继续构建DOM
因此script的位置很重要,在实际使用过程中遵循以下两个原则:
当我们生成DOM树和CSSOM树后,我们需要将这两颗树合并成渲染树,渲染步骤包括样式、布局、绘制
主线程会遍历得到DOM树,依次为树中每个节点计算出它最终的样式,称之为Computed Style
这一过程中,很多预设值会变成绝对值,比如 red会变成rgb(255,0,0)相对单位会变成觉得单位 em 变成px。
浏览器拿到渲染树后,就会从渲染树的根节点开始遍历,然后确定每个节点对象在页面上的确切大小与位置,通常这一行为也被称为“自动重排”。布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小,所有相对测量值都将转换为屏幕上的绝对像素。这一过程也可称为回流。
分层是占用内存空间的,主线程会使用一套复杂的策略对整个布局树进行分层,分层的好处在于,将来某一个层改变后,仅会对该层进行后续处理,重而提升效率。
在绘制或光栅化阶段,浏览器将在布局阶段计算的每个框转换为屏幕上的实际像素。绘画包括将元素的每个可视部分绘制到屏幕上,包括文本、颜色、边框、阴影和替换的元素(如按钮和图像)。浏览器需要非常快地完成这项工作。
在我们了解浏览器的渲染机制后,DOM 和 CSSOM 结构构建顺序,我们可以针对性能优化问题给出一些方案,提升页面性能。
当元素的样式发生变化时,浏览器需要触发更新,重新绘制元素。这个过程中,有两种类型的操作,即重绘与回流。
注意:回流一定会触发重绘,而重绘不一定会回流,重绘的开销较小,回流的代价较高
因此为了减少性能优化,我们可以尽量避免回流或者重绘操作 css
javascript
defer 和 async 属性的区别:
其中蓝色线代表JavaScript加载;红色线代表JavaScript执行;绿色线代表 HTML 解析 1)情况1
2)情况2 (异步下载) async 属性表示异步执行引入的 JavaScript,与 defer 的区别在于,如果已经加载好,就会开始执行——无论此刻是 HTML 解析阶段还是 DOMContentLoaded 触发之后。需要注意的是,这种方式加载的 JavaScript 依然会阻塞 load 事件。换句话说,async-script 可能在 DOMContentLoaded 触发之前或之后执行,但一定在 load 触发之前执行。
3)情况3
defer 与相比普通 script,有两点区别:
js优化可以在script标签加上 defer属性 和 async属性用于在不阻塞页面文档解析的前提下,控制脚本的下载和执行
其他: CSS 标签的 rel属性 中的属性值设置为 preload 能够让你在你的HTML页面中可以指明哪些资源是在页面加载完成后即刻需要的,最优的配置加载顺序,提高渲染性能