关键渲染路径就是描述浏览器从HTML、CSS和Javascript字节开始,到如何使用HTML、CSS和Javascript在屏幕上渲染像素的中间过程。
全景图
- DOM 处理HTML标记并构建DOM树
JavaScript
- CSSOM 处理CSS标记并构建CSSOM树
- Render Tree 将DOM与CSSOM合并成一个渲染树
- Layout 根据渲染树来布局
- Paint 将各个节点绘制到屏幕上
文档对象模型
DOM树的构建流程:字节》字符》标签对》节点》对象模型
这个过程在浏览器中叫做"Parse HTML"。
CSS 对象模型(CSSOM)
获取了DOM内容,还需要展示这些内容,浏览器需要构建CSS对象模型,浏览器在解析DOM时遇到了link标签,如果是使用的外部样式资源,浏览器回向外部请求样式资源,然后进行后续的DOM构建工作。
CSS被视为阻塞渲染的资源,这意味着浏览器将不会渲染任何内容,需要等待CSS对象模型构建完毕再渲染。
CSSOM的构建过程:字节》字符》令牌》节点》CSS对象模型
转化好的树形结构让CSS有层级继承关系,子节点会继承父节点的样式。
CSSOM运算性能消耗比较大,写样式尽量保证层级扁平,减少过度层叠。
DOM + CSSOM = 渲染树
渲染树和DOM树不同,渲染树只会捕获页面上可见的元素。像Header标签内的元素 或者display: none的元素不会放在渲染树中。
渲染树的构建会从body根节点开始遍历,对于不可见节点会忽略。然后在CSSOM中找到每个对应节点的样式规则并应用。最后输出的渲染树会包含所有可见内容和样式信息。
布局和绘制
有了渲染树,浏览器会进入布局和绘制阶段。
布局:每个元素的大小和位置和尺寸。
绘制:将渲染树转换成屏幕上的像素。
当DOM或者CSSOM发生变化的时候,浏览器就需要再执行一次关键渲染路径的步骤。
Javascript
js在关键渲染路径中起到举足轻重的作用。脚本在文档的何处插入,就在何处执行。
当HTML解析过程中遇到一个script标记时,它会暂停DOM构建,将控制权移交给Javascript引擎。等js引擎运行完毕,浏览器再从中断的地方恢复DOM构建。也就是说,执行内联的js会阻塞页面的首次渲染。
如果遇到外部引入的js,浏览器会渲染阻塞直到write.js的请求返回后,并执行js后。才会继续渲染。
link的请求不仅阻塞后面的渲染,还阻塞来DOM的构建。
对于常见的页面结构。js和css资源的请求是并行的,但仍然需要等到cssom构建完成之后,js才可以执行,然后在后面的渲染工作。当DOM、CSSOM、和Javascript执行之间有大量的依赖关系时,就很可能导致浏览器在处理及渲染网页时出现延迟。
优化策略
第一步,分析网址渲染状况
Performance中的四条竖线分别是什么含义?
- 绿色竖线,代表First Paint, 即浏览器开始进行像素的绘制。
- 黄色竖线,代表First Meaningful Paint (首次有效绘制) 用户可以开始看到部分内容,但是绘制仍在继续
- 蓝色竖线,代表大家比较熟悉的DOMContentLoaded
- 红色竖线,代表load,页面加载完成
优秀的网址都能够把“首次有效渲染”做到1秒之内完成,这样能够让用户更快的看到所请求的页面得到响应。
第二步,分析关键渲染路径
我通常关注的三个点:
- 页面首次渲染需要的关键资源数量
- 关键资源的大小
- 关键渲染路径的往返次数(Roundtrip)
策略:减少关键资源数量,降低资源大小,减少关键路径的往返次数
主站图片请求太泛滥了
根据分析采取优化手段
1.减少关键资源的大小
去除无用的代码和注释,最小化代码
2.延迟JavaScript非阻塞资源加载
js和css都是阻塞渲染的资源,对于首次渲染没有起到关键作用的代码,我们可以延迟它的加载,让它脱离关键渲染路径。
将js放置在body的底部
非阻塞渲染的js,我们应该采用异步的方式加载。
<script async src="script.js"></script>
<script defer src="myscript.js"></script>
async defer???
async 不适合包含有Dom操作的js文件
defer html 的解析和对js资源的网络请求是并行的,但它会等到html解析完成之后,才执行脚本。
3.尽早按需加载CSS
页面应该只引用与该页面相关的样式文件
避免在首次渲染的css的样式中使用@import指令,因为它只有在继续完成带有@import的资源后,会重新请求,从而增加了关键渲染路径的往返次数。
4.内联CSS来提高渲染性能
在head内联样式:google 百度 淘宝 京东
5.一个神奇的数字14kb
http的传输层协议是Tcp,tcp协议有一个慢启动的过程,即它在第一次传递数据时,只能同时传递14kb的数块,所以当数据超过14kb时,tcp协议传递数据实际是多次的往返。如果能够将渲染所需要的资源控制在14kb之内,那么就能tcp协议启动时,一次完成数据的传递。
其他web资源和关键渲染路径的关系
图片不是阻塞渲染的资源,它的痛点主要是质量和资源大小的权衡,以及请求数量带来的性能消耗。
主站一定要引入雪碧图,网络字体需要了解。
总结
优化关键渲染路径的最终目的是优先显示和用户操作相关的内容,减少低优先级资源对浏览器渲染的阻塞,从而尽早显示用户真正关心的关键内容。页面性能就是用户体验的一个重要纬度,常识用感性的思维去思考理性的代码,也许真的能受益不少。
浏览器渲染路径的精品文章,需要再看两边笔记来吸收。