浏览器是如何将一个网页渲染出来的?

241 阅读4分钟

一、 浏览器渲染原理

通过网络获取html文件,然后解析html文件,最后渲染在浏览器上给用户看到。

image.png

二、渲染的时间点

浏览器通过网络进程进行通信获取到html文件,然后在消息队列中创建渲染任务进行排队,最后交给渲染主线程进行渲染。

image.png

三、渲染流水线

image.png

1. 解析HTML - Parse HTML

HTML会被解析成DOM树和CSSOM树

image.png

DOM树

image.png

CSSOM树

image.png

HTML 解析过程中遇到 CSS 代码怎么办?
为了提⾼解析效率,浏览器会启动⼀个预解析器率先下载和解析 CSS

image.png

HTML 解析过程中遇到 JS 代码怎么办?
渲染主线程遇到 JS 时必须暂停⼀切⾏为,等待下载执⾏完后才能继续,预解析线程可以分担⼀点下载 JS 的任务

image.png

2. 样式计算 - Recalculate Style

根据解析出来的dom树和cssom树进行样式计算,将dom树和cssom树结合在一起

image.png

3. 布局 - Layout

根据结合的dom树和cssom树,会生成一个layout树

image.png

其中,dom树和layout树不是一一对应的。例如:样式中有display: none、伪元素或者html树中有文本等,都会使dom树和layout树不一样

image.png

image.png

image.png

4. 分层 - Layer

浏览器会根据layout树进行分析对内容分层,哪一部分是会进行频繁改变和哪一部分是相对稳定的,将会分层出来

image.png

5. 绘制 - Paint

根据计算的分层,为每一层生成如何的绘制指令。

image.png

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

6. 分块 - Tiling

分块会将每一层分为多个小的区域

image.png

分块的工作是交给多个线程同时进行的

image.png

7. 光栅化 - Raster

光栅化是将每个块变成位图,优先处理靠近视口的块

image.png

此过程会用到GPU加速

image.png

8. 画 - Draw

合成线程计算出每个位图在屏幕上的位置,交给GPU进行最终的呈现

image.png

这样一个网页也就被渲染出来了。

四、渲染的完整过程

  • 渲染主线程对html进行解析,生成dom树和cssom树
  • 根据dom树和cssom树计算样式,从而再生成layout树
  • 根据layout树再进行分层计算,生成每一层的绘制指令,渲染主线程完成工作
  • 合成线程根据分层信息对每一层进行分块处理
  • 然后将分块进行光栅化,将每个块变成位图,优先处理视口中的块
  • 最后再计算每个位图在屏幕中的位置,然后通过GPU渲染在屏幕上

image.png

五、常见的一些问题

1. 什么是重排(reflow)?

重排(reflow)指的是当网页中的元素发生变化,影响到元素的布局和几何属性(例如尺寸、位置等)时,浏览器需要重新计算元素的布局,并重新渲染页面的过程。

image.png

从过程图可以看到,重排也就是又从解析html开始进行一遍渲染过程,所以频繁的重排是十分损耗性能的,开发时应该尽量避免。

如何减少重排?
  • 批量修改 DOM: 尽量一次性修改多个 DOM 属性,而不是频繁地逐个修改。
  • 使用 CSS3 动画: CSS3 动画通常由 GPU 渲染,不会触发 Reflow。
  • 避免使用 table 布局: table 布局容易触发 Reflow。
  • 减少使用 inline-style: 尽量使用外部样式表或内部样式表。
  • 避免频繁读取 offsetWidth/offsetHeight 等属性: 这些属性会强制浏览器进行 Reflow。

2. 什么是重绘(repaint)?

重绘 (Repaint) 指的是当网页中的元素样式发生变化,但不影响元素的布局和几何属性(例如尺寸、位置等)时,浏览器会重新绘制该元素,但不会重新计算布局。简单来说,就是元素的外观发生了变化,但它在页面中的位置和大小没有改变

image.png

从过程图中可以看到,重绘是从样式计算这一步开始重新进行,对比重排少了一步解析html,所以频繁的重绘也是十分损耗性能的。

如何减少重绘?
  • 使用 CSS3 动画: CSS3 动画通常由 GPU 渲染,可以减少重绘的发生。
  • 避免频繁修改样式: 尽量一次性修改多个样式属性,而不是频繁地逐个修改。
  • 合理使用 will-change 属性: will-change 属性可以提前告知浏览器元素将要发生的变化,从而进行优化,但过度使用可能会导致性能问题。

3. 为什么 transform 效率⾼?

transform的修改不触发布局阶段(Layout/Reflow)和绘制阶段(Paint) ,仅影响合成阶段(Composite)。

image.png

image.png