浏览器数据解析与页面绘制

1,154 阅读3分钟

浏览器绘制页面

这篇文章的主要内容是介绍浏览器在服务器获取到HTML、CSS、JavaScript等资源后的数据解析以及页面渲染的过程。也介绍了部分React生命周期钩子(ComponentDidMountComponentDidUpdate)及Hooks(useEffectuseLayoutEffect)对应的调用时期。

数据解析是浏览器将数据解析为 DOM树🌲、CSSOM树🌲 的过程。

页面渲染是将可见元素的布局绘制在屏幕🖥上的过程。

在页面渲染到屏幕之前,HTML、CSS、JavaScript等必须被解析完成。

数据解析

数据解析分为两个部分:首先被完成的是构建 DOM树🌲

DOM树

获取到HTML文件后,先处理HTML标记,构建DOM树。HTML标记分为开始结束标签、属性以及数据值。

DOM树.jpg 当解析器遇到非阻塞文件,解析器就会请求这些文件并继续解析。 如果遇到阻塞文件,解析过程就会被阻塞。例如:未带有 async、defer 的JavaScript文件。

构建DOM树🌲过后,是构建CSSOM树🌲

CSSOM树

第二个步骤是构建CSSOM树🌲,CSSOM树与DOM树是相似的,构建CSSOM树速度特别快。

接下来就开始渲染环节。

页面渲染

渲染环节包括样式、布局、绘制,有的情况下还包括合成。在数据解析过程中解析出来的DOM树🌲CSSOM树🌲 组合形成Render树🌲,Render树计算每个可见元素的布局,然后绘制到屏幕🖥上。

页面渲染分为三个部分:第一部分就是组合成Render树🌲

Render树

第一部是DOM树🌲CSSOM树🌲 组合形成Render树🌲,计算样式树或渲染树从DOM树的根开始构建,遍历每个可见节点。

display: none 不会出现在Render树上,visibility: hidden 会出现在Render树上,因为会占用空间。

Render树保存所有具有内容和计算样式的可见节点。下一步是布局。

Layout

在Render树上布局、计算每个元素的高度、宽度以及位置。

第一次确定节点的大小和位置称为布局。随后对节点大小和位置的重新计算称为回流。延迟获取到的图像会发生回流。最后一步是绘制。

其中useLayoutEffet()ComponentDidMountComponentDidUpdate就在这个阶段进行。这里可以直接调用 setState() 。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前。useEffect() 里的函数在浏览器渲染之后在一个延迟事件中被调用。

绘制

最后一步是将各个元素绘制在页面上。

绘制可以将布局树🌲中的元素分解为多个层。

为了确保重绘的速度比初始绘制的速度更快⚡️,屏幕上的绘图通常被分解成数层。如果发生这种情况,则需要进行合成。

层确实可以提高性能,但是它以内存管理💾 为代价,因此不应作为web性能优化策略的一部分过度使用。

合成

当文档的各个部分以不同的层绘制,相互重叠时,必须进行合成,以确保它们以正确的顺序绘制到屏幕上,并正确显示内容。

当页面继续加载资产时,可能会发生回流(回想一下我们迟到的示例图像),回流会触发重新绘制和重新组合。

如果我们定义了图像🎑的大小,就不需要重新布局,只需要重新绘制需要绘制的层,并在必要时进行合成。但如果我们没有定义图像大小!从服务器获取图像后,渲染过程将返回到布局步骤开始。

参考资料