全部 / 前端 / 技术 · 2021年7月4日 0

关键渲染路径-构建对象模型

广告位招租 (vx: ghostcode, 备注:网站广告)

在浏览器渲染页面之前,需要构建DOM 和 CSSOM 树。因此,我们需要尽快的把 HTML 和 CSS 发送给浏览器。
简介:

  1. 字节-> 字符-> 符号-> 节点-> 对象模型
  2. HTML 节点会转换成 DOM,CSS 会被转成 CSSOM
  3. DOM 和 CSSOM 是独立的数据结构
  4. 我们可以通过 Chrome 的开发工具来截取和侦测到构建和处理 DOM 和 CSSOM 时的开销

DOM

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="style.css" rel="stylesheet">
    <title>Critical Path</title>
  </head>
  <body>
    <p>Hello <span>web performance</span> students!</p>
    <div><img src="awesome-photo.jpg"></div>
  </body>
</html>


让我们以一个简单的例子开始:一个简单的 HTML 页面,里面包括文本和一个图片,浏览器会如何处理这个页面?

1. 转换:浏览器从硬盘或者网络读取到原始的HTML字节,然后根据文件的指定编码来转换它们为独立的字符。
2.符号化:浏览器根据 W3C HTML5 的标准把字符转换为不同的符号,例如:“html”、“body” ,每个符号都有特殊的含义和一系列它们自己的规则。
3.词法分析:生成的符号会被转换为“对象”,以此来定义它们的属性和规则
4.DOM 生成:最终,因为 HTML 的结构定义了不同标签之间的关系,所以创建的对象之间也形成了树的关系,也就有了父子关系:HTML 对象是 body 对象的父级,body 又是 paragraph 的父级,以此类推。

我们的简单页面最终生成的是 DOM,浏览器以此来对页面进行更进一步的处理。浏览器每次处理 HTML 时,都会按照上面的步骤走一遍。整个处理过程会耗费一些时间,特别是当有大量的 HTML 需要处理的时候。

如果你打开 Chrome 的开发工具并在页面加载的时候记录了 Timeline ,可以精确的看到此过程花费的时间。从上图看出从 HTML 转换为 DOM 消耗了大概 5ms,若是一个更大的页面,这个过程会消耗更多时间。当创建流程的动画时,处理大量的 HTML 会很容易成为瓶颈。
DOM 虽然获取了文档标记的属性和关系,但是并没有让我们看到元素是如何渲染的,这个功能是CSSOM来负责的。
CSSOM当浏览器构造 DOM 时,当在 head 上遇到一个 link 标签指向外部的样式文件:style.css 。浏览器需要这个资源来渲染页面,则会发送一个请求,然后得到返回的内容:

body { font-size: 16px }
p { font-weight: bold }
span { color: red }
p span { display: none }
img { float: right }

我们可以在多个地方声明 CSS: HTML 标签上、外部独立的链接、Style 标签里。
正如 HTML 一样,我们需要把得到的 CSS 转换为浏览器认识、识别的内容。因此又重复了类似 HTML 的过程:

CSS 字节转化为 字符、符号、节点最后连成一个树结构:CSSOM。

为何 CSSOM 有一个树结构?当给页面上的任何一个对象计算最终样式时,浏览器使用通用的规则来应用到节点上(例如,如果它是 body 的子节点,则会应用上 body 上可继承的熟悉)。
为了更形象具体一些,让我们来看上面的 CSSOM,在 span 中的文本都在 body 元素下,文本具有 font-size:16 以及 color:red 属性。font-size 是从 body 中继承的。
还有,需要注意的是上面的 CSSOM 并不是全部的样式,因为每个浏览器都有默认样式:“user agent styles”,就是在没有提供任何自定义样式时页面展示的样子。
为了可以看到处理 CSS 花费了多长时间,可以在 timeline 中记录并查看,与 DOM 不同的是没有单独的 “Parse CSS” 入口,而是包括解析、CSSOM 创建以及递归计算的样式总耗费时间。

此页面总耗时为 0.6 ms,最后,CSSOM 和 DOM 是独立的数据结构,是如何联系在一起的? 浏览器隐藏了一个重要的步骤,这就是下次要讲解的连接 DOM 和 CSSOM 的渲染树。