Skip to content

渲染进程

这部分的知识点可以判断一个人是否是专业搞前端的。业余和职业的分水岭。很多优化是跟这个知识密切相关的。

渲染:浏览器端将 html 字符串 -> 像素信息,整个过程称之为渲染。

渲染时间点发生在什么时候呢?

网络进程的网络线程通信之后拿到html之后,生成一个渲染任务给任务队列。等待主线程运行这个渲染任务,去进行渲染。

渲染流水线

解析 HTML -> 样式计算 -> 布局 -> 分层 -> 绘制 -> 分块 -> 光栅化 -> 画

解析 HTML

这个过程会讲 HTML 字符串转化为两棵树,分别是 DOM 树 和 CSSOM 树

之所以需要转为 树形结构, 是因为 字符串信息 是非常的难以操作的,给后续步骤做准备

html 解析过程中遇到 CSS 代码怎么办?

为了提高效率,浏览器会开启一个预解析线程,先去下载那些远程的 CSS 和解析 CSS,之后交给主线程生成 CSSOM 树。 所以说 CSS 的解析不会阻塞 HTML 的解析的,因为本质上他们跑在不同的线程上。

JS 为什么不需要生成树?

JS 的代码只需要执行一次就好了,不像 HTML 和 CSS 一样后续还需要使用。只不过 JS 解析是会停止解析 HTML 的,因为 JS 的执行可能会改变 DOM 树,所以这个过程是必须会暂停的,这也就是为什么 JS 会阻塞 HTML 解析的根本原因。

计算样式

得到每个节点的最终样式(计算后的样式),这部结束之后会得到一个带有样式的 DOM 树

布局-Layout

根据 DOM 树(上一步骤 DOM 树已经有样式信息了),算出每个节点的 尺寸 和位置。生成 LayOut 树。

DOM 树和 Layout 树是不一样的。有一些 DOM 信息是隐藏的(display:none),不需要展示在页面上的。(只有是有几何信息的,才会在布局树上)

分层 Layer

非常类似于 PS 中的图层。跟堆叠上下文有关的 CSS 属性可能会影响到分层,如(z-index

好处在于将来某个层改变之后,只对这个层操作就好,不需要做全量的操作。这是浏览器自己的一个性能优化手段。

绘制

这里的绘制,是为每个元素生成一个绘制的指令。这个步骤和 canvas 是非常类似的。

主线程的工作到此为止,剩余的步骤都是交给其他线程完成的。

分块

分块会将每一层分为多个小的区域。分块的工作是交给多个线程同时进行的。

光栅化

光栅化就是将每个块变成位图,有线处理靠近视口的块(分块的优化目的)。这步骤是 gpu 进程做的。gpu 的运算速度是会高出 cpu 很多的。

GPU 进行最终的呈现。

面试题集合

面试题

什么是 reflow

reflow 的本质就是重新计算 layout 树。

当进行了会影响布局树的操作后,需要重新计算布局树,树引发 layout

为了避免连续多次操作布局树儿导致的反复计算,浏览器会合并这些操作,当 JS 代码全部完成后再进行统一的计算。所以,改动属性造成的 reflow 是异步完成的。

也同样是因为如此,当 JS 获取属性时,就可能在成无法获取最新的布局信息。

浏览器在反复权衡下,最终决定获取属性立即生效 reflow

这样就是为了我们建议 设置属性全部一起设置, 再一起获取。本质上是性能优化。

面试题

什么是 repaint

改变颜色等,不会引发几何图形的变化。reflow 一定会导致 repaint

面试题

什么 transform 效率高

transform 改变的是渲染过程中最后一步"画"的过程,所以它的效率是极高的!且它的执行不在主线程上的。