浏览器是怎样渲染页面的

TLDR,页面的关键渲染路径

  • 构建对象模型(Object Model)
    • 构建 DOM(文档对象模型)
    • 构建 CSSOM(CSS 对象模型)
  • 构建渲染树(Render Tree)
  • 布局(Layout)
  • 绘制(Paint)

从浏览器接收到 HTML内容时便开始了这一系列的工作。理解浏览器渲染过程是优化 Web 性能的基础。

构建对象模型

浏览器接收到 HTML、CSS 后便开始了对象模型的构建。

对象模型(Object Model)是一种数据结构,HTML 和 CSS 都可以通过对象模型来描述。HTML 会被浏览器解析构建为 DOM,CSS 则会被解析构建为 CSSOM。

他们都遵循一套类似的解析、构建流程:

  • 转换:把接收到的原始字节根据指定的编码转换成字符;
  • Token 化:将字符串根据规范和标记解析为 Token 令牌;
  • 词法分析:将 Token 转换成定义其属性和规则的 “对象节点”;
  • 构建:将“ 对象节点“ 根据层级关系构建成树状数据结构;

文档对象模型 DOM

DOM Tree 构建流程

CSS 对象模型 CSSOM

有了 CSSOM 浏览器就可以在在渲染时从节点最通用规则开始(如果该节点是 body 的子元素,则应用所有 body 样式),然后向更具体的规则(向下级联)递归的优化计算的样式。

CSSOM Tree

需要注意的是,通过用户的样式表构建出来的还不是一个完整的 CSSOM,还需要与浏览器默认样式(User agent style)进行合并后才能得到完整的 CSSOM。

预加载扫描器

在浏览器构建 DOM 过程中并不是解析到了 link、script 标签才开始加载对应的外部资源,而是会进行预加载扫描,使得关键资源能提前加载减少阻塞时间。

查看构建对象模型的耗时

构建对象模型的耗时与文档内容息息相关,我们可以通过浏览器调试工具来观察渲染过程和耗时情况。

构建渲染树

当 DOM 和 CSSOM 构建完成后浏览器将会对他们进行合并,组成一颗渲染树(Render tree)。

Render tree

DOM 包含了文档内所有的节点,但 Render tree 会通过 CSSOM 来过滤掉不需要渲染的节点。这些不需要渲染的节点例如某些 meta 标签、注释和被 CSS 隐藏的元素等。

需要注意的是 visibility: hidden 的元素虽然会被隐藏但还是占据着自身的位置,是会被包含在渲染树中的。

布局

渲染树构建完成后就进入到布局(Layout)阶段。浏览器从渲染树的根节点开始进行遍历,通过盒模型来计算渲染树中所有节点元素的的宽度、高度及页面上的位置,并将所有相对测量值都转换为屏幕上的绝对像素。

第一次确定节点的大小和位置称为布局。随后对节点大小和位置的重新计算称为回流

渲染

最后的步骤则是将节点绘制到屏幕上。

浏览器绘制页面的时间取决于页面内容的多少和样式复杂程度。例如绘制普通的边框要比绘制阴影速度要快上许多。

另外,为了提升重绘的速度,浏览器还会将绘制内容进行分层,使得重绘时仅绘制必要的内容,通过分层绘制时还需要对页面中重叠的部分进行合成。分层可以提高性能,但是它以内存管理为代价。

为了保证页面的流畅我们需要以每秒 60 帧刷新页面。也就是说从每一次构建对象模型、计算样式、回流、重绘需要在 16.66ms 内完成,超过这个时间用户则会感觉到页面卡顿。

关键渲染路径

上面我们了解了浏览器渲染页面的流程:构建 DOM、构建 CSSOM、构建渲染树、布局、绘制。

这五个关键流程也叫做浏览器的 “关键渲染路径”。上面仅仅是理想情况下的页面渲染过程,实际上会有许多 “东西” 阻塞关键渲染路径,我们对 Web 性能的优化也是围绕着关键渲染路径来展开的。

相关文章:

JS CSS 是如何阻塞页面渲染的 – 龚为的 Blog

渲染页面:浏览器的工作原理 – MDN

关键渲染路径 – Google Developers

关键渲染路径 – berwin/Blog

发表评论

邮箱地址不会被公开。 必填项已用*标注