关键渲染路径是浏览器将 HTML,CSS 和 JavaScript 转换为屏幕上的像素所经历的步骤序列。优化关键渲染路径可提高渲染性能。关键渲染路径包含了 文档对象模型 (DOM),CSS 对象模型 (CSSOM),渲染树和布局。
步骤序列
- 构建文档对象模型(生成DOM tree)
- 构建CSS对象模型(生成CSSOM tree)
- 构建渲染树(生成Render tree)
- 布局(渲染树节点转为像素)
- 绘制(计算像素渲染到屏幕上)
步骤分解
生成DOM
第一步就是生成DOM对象。实际上你从网络上获取的是字节,而浏览器使用的是所谓的DOM树。因此需要将这些字节转换为DOM树。
- 你以字节形式接收页面。你的浏览器将其转换为文本
- 文本被转换为节点
- 节点被转换为“对象”
- 生成所谓的DOM树
你可以通过开发者工具查看此过程的耗时
我们看到它消耗了4.938ms
当这个过程完成后时,浏览器将拥有页面的全部内容,但是为了能够渲染,浏览器必须等待CSS对象模型,也被称为CSSOM事件,它会告诉浏览器元素在渲染的时候应该是什么样子
生成CSSOM
对于CSS来说和上面提到的一样,浏览器需要将这些文件转换为CSSOM
CSS也是一个树结构。实际上,如果你将font-size放到父元素上,那么子元素将会继承它
在开发者工具里边被称为 recalculate style
CSS是关键渲染路径中最重要的元素之一,因为浏览器会阻塞渲染,直到接收完和处理完页面中所有的css文件,所以CSS会阻塞渲染
生成 Render Tree
CSSOM和DOM结合起来显示
布局
一切都必须以像素为单位进行计算。所以当你说一个元素的宽度为50%时,在幕后浏览器会将其转换为像素:
每次对渲染树进行更新或者视口大小发生改变,浏览器必须再次进行布局
绘制
此步骤是将所有这些转换为屏幕上的像素。这就是渲染步骤
js的影响
对于js的声明周期,你可以查看这篇
js的要点就是:你可能最关心的事件是DOMContentLoaded
。这是DOM准备就绪的时候。
当浏览器最初加载html时,并在文本中遇到内联 <script>...</script> ,它无法继续构建DOM。它必须立即执行script。所以 DOM Content Loaded 只有可能在所有这样的脚本执行完后才会发生。
外联script(带有src属性)也会在脚本加载和执行的时候暂停DOM构建。所以DOM Content Loaded同样也会等待外联脚本
唯一的里外就是外联脚本有
defer
或者async
属性。他们告诉浏览器继续处理而不必等待脚本。因此用户可以在script加载前先看到页面,这样对提升性能很有帮助。【译文】async vs defer
注意:
- js在执行时如果CSSOM未完成,会等待CSSOM完成后再开始进行解析
- 如果存在多个js,第一个js加载的时候,会通过预加载扫描程序来发现CSS和JS资源并同步下载