3.1 关键渲染路径 Critical Rendering Path

发布于 2022-05-02 12:55:45 字数 7275 浏览 1034 评论 0

前言

分析 CRP 的核心指导思想是:Measure first, optimize second 先分析瓶颈,再谈性能优化。理论只能作概念性指导,不一定跟具体浏览器的实现相同。一切以浏览器当前行为为准,因为必须先分析。

Analyzing Critical Rendering Path 是官网文档系列中最高屋建瓴的一篇,推荐先阅读。

正文

CRP 有五个阶段,如果把它当成一个 API,那么它的输入和输出就是:renderedPage = CRP(plainHTML)。它接受一个 HTML 文件,渲染出一张网页来。对这个 API 的实现做一下任务分解,我们可以拆分成五个方法:

function criticalRenderPath(htmlPage) {
  let cssFiles = plainHtml.getAllCss().download()

  let documentObject = dom(plainHtml)
  let cssObject = cssom(cssFiles)
  let renderTree = combineVisible(documentObject, cssObject)
  let layout = calculateLayout(renderTree)
  let rendered = paint(layout)

  return rendered
}

DOM 构建 Constructing Document Object Model (DOM)

DOM 是什么?为什么要构建 DOM?因为静态的 html 文件是无法渲染的,浏览器需要把它变成一个内存中的数据结构。那么就一定是使用对象(这个概念)来描述了。所以关于文档的对象就叫文档对象模型(DOM)。

更准确来说,DOM 是一套 API,提供了对 HTML/XML 等标记语言的结构化(对象)表述,同时它定义了一套对文档对象进行操作的 API。

The Document Object Model (DOM) is a cross-platform and language-independent application programming interface that treats an HTML, XHTML, or XML document as a tree structure wherein each node is an object representing a part of the document. The objects can be manipulated programmatically and any visible changes occurring as a result may then be reflected in the display of the document. - Wikipedia

  • 上面强调了 visible,它是由 DOM 渲染成为页面过程一个关键的取舍因素
  • DOM 是一种概念模型。虽然它叫对象模型,但并不一定需要以『对象』的方式来实现,这是由浏览器引擎的实现决定的。因为是一种概念模型,才可能跨平台、语言实现无关
  • 它采用了对象来描述文档。表述方式也可以不是对象,只不过对象模型利于面向对象语言的实现
  • 既然是 API,就规定了一套操作元素——『对象』——的接口,它对文档反过来有影响

DOM 介绍精华资料:

进一步细分构建 DOM 这个操作,我们又可以把 dom(htmlPage) 这个函数拆分成几步:

function dom(htmlPage) {
  let bytes = readBytes(htmlPage)
  let characters = interprets(bytes, encoding = 'utf-8')
  let tokens = tokenize(characters, specification = 'HTML5')
  let nodes = construct(tokens)
  let dom = connects(nodes)

  return dom
}

image

image

生成的这个 DOM 有什么用呢?它是构建渲染树的原材料,同时也是其对应静态 HTML 页面的内存描述

.css / .js 会在什么时候被下载?

根据这两篇资料的回答: W3C HTML5: A vocabulary and associated APIs for HTML and XHTML#html-syntax How Browser Work: Behind the scenes of modern web browsers,它们是在 tokenizer 进行 tokenization 的时候进行的。tokenizer 内部有非常复杂的状态与规则来维护和支持 tokenize 之外的操作。

CSSOM 构建

CSS 的下载时机上面已讲,在分析 HTML、进行 tokenization 的时候发生。一般下载到以后马上就构建 CSSOM 树。如果没下载到,料想浏览器也不会因此阻塞渲染树的构建。

CSS 是需要渲染完整性的,它必须被完全下载、构建成 CSSOM 树后才能使用,因为任何未完整的 CSS 树都可能被覆盖。不过,在当代浏览器实现中,CSSOM 的构建应不阻塞 DOM 和 Render tree 的构建和渲染。

CSSOM 的构造过程与 DOM 的构造过程很像:字节读取、字符识别、tokenization、转换成 CSS 节点、构造成 CSSOM。只是 tokenization、CSS 节点转换的过程需要查询不同的规范定义而已。HTML/CSS 有各自合法的 token、节点定义。详见各自的规范,CSS 规范在此:https://drafts.csswg.org/cssom/

image

这个树结构暗示了,CSS 样式的应用具有继承关系,这也是它被称为层叠样式表的原因,样式的应用汇向下层叠,并以更具体的选择器样式为准。更具体的选择器 selector 需要更多的 CPU 计算时间,因而会占用更长的加载时间,主要是因为引擎需要遍历更多的节点、寻找它们的关系。

很多时候,即使我们什么样式都没写,渲染出来的文本也会有最基本的样式。这是浏览器为我们提供的基本样式:user agent styles。每个浏览器提供的 UAS 可能会有所不同。

渲染树 render tree

The CSSOM and DOM trees are combined into a render tree, which is then used to compute the layout of each visible element and serves as an input to the paint process that renders the pixels to screen. Optimizing each of these steps is critical to achieving optimal rendering performance.

DOM 和 CSSOM 分别描述了待渲染网页的内容和样式,加上 visible 这个筛选器后,就变成了一棵具备了足够的信息告诉浏览器,渲染什么样式的哪些内容给用户看。渲染树只包含需要渲染的元素。这个关系式如下:

let renderTree = visible(dom, cssom)

image

两大类“不可见”的节点 Nodes 会在归并渲染树🌲的时候被砍掉:

  • 本身对用户不可见的节点,比如 <meta><link><script>
  • 被 CSS 设置为不可见的节点,比如 p span { display: none; } 等节点
  • 没有高度、超出画面等“逻辑”上用户看不见的节点,也必须是渲染树的一部分,因为它会影响其他元素的布局。浏览器必须知道它们的存在,才能正确渲染其他元素

image

可以发现,CRP 及其子任务在逻辑上是非常线性的工作流。在实际实现中,浏览器可能会为了最大程度加速网页渲染,最大程度地并行可并行的任务。

布局 Layout

上一步得出的渲染树已经是可以渲染在页面上所有内容及它们对应的样式,这一步,我们需要计算它们所占据的实际大小和位置。这一步会产出一个盒模型

绘制 Painting

不管在哪个步骤中,尝试能使用 Timeline 分析出每个部分渲染的时间,以及它们与预期范围的对比,是项重要的技能。布局和绘制部分我们放在下一节讲。

render 也叫 reflow,paint 也叫 repaint,前者需要重新计算位置,属 CPU 密集型操作;后者只需要重绘,属 GPU 类型操作。后者明显快于前者。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

遂心如意

文章 0 评论 0

5513090242

文章 0 评论 0

巷雨优美回忆

文章 0 评论 0

junpengz2000

文章 0 评论 0

13郎

文章 0 评论 0

qq_xU4RDg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文