浏览器渲染页面流程

137 阅读5分钟

在前端开发中,了解浏览器如何将 HTML、CSS 和 JavaScript 转换为用户最终看到的页面,对于性能优化、问题排查以及构建高效应用至关重要。

目录

  1. 浏览器渲染流程概览

  2. 关键渲染路径的组成部分

    • 2.1 构建 DOM 树
    • 2.2 构建 CSSOM 树
    • 2.3 构建渲染树
    • 2.4 布局(Layout/Reflow)
    • 2.5 绘制(Paint)
    • 2.6 合成(Composite)
  3. 优化关键渲染路径的策略


1. 浏览器渲染流程概览

当用户在浏览器中请求一个网页时,浏览器会经历一系列复杂的步骤,将服务器返回的 HTML、CSS 和 JavaScript 转换为可视化的页面。这个过程主要包括以下步骤:

  • 解析 HTML:浏览器将 HTML 文档解析为一个 DOM(文档对象模型)树,表示页面的结构。
  • 解析 CSS:浏览器解析所有 CSS 文件和内联样式,生成 CSSOM(CSS 对象模型)树,描述每个元素的样式规则。
  • 构建渲染树:将 DOM 树和 CSSOM 树合并,生成渲染树,渲染树仅包含页面上实际需要显示的节点和其样式信息。
  • 布局(Reflow) :根据渲染树,计算每个节点在页面上的精确位置和尺寸。
  • 绘制(Paint) :将计算好的页面信息转换为实际的像素,将各个节点的内容绘制到屏幕上。
  • 合成(Composite) :将页面拆分为多个图层,分别渲染后再组合成最终呈现的页面。

这个完整的流程决定了页面加载和呈现的速度,是前端性能优化的重要依据。


2. 关键渲染路径的组成部分

关键渲染路径(Critical Rendering Path)是指浏览器从接收到 HTML/CSS 到首次呈现页面所经历的关键步骤。优化关键渲染路径可以显著提升页面加载速度和响应性能。下面详细介绍每个阶段:

2.1 构建 DOM 树

  • HTML 解析:浏览器解析 HTML 文件,将其转换为 DOM 树。
  • DOM 树:由节点组成的树形结构,描述了页面的结构和层次关系。
  • 注意:遇到 <script> 标签时可能会暂停解析,直到脚本加载和执行完毕(除非使用 asyncdefer)。

2.2 构建 CSSOM 树

  • CSS 解析:浏览器解析所有外部和内联 CSS,形成 CSS 规则集合。
  • CSSOM 树:描述页面中每个元素的样式信息,独立于 DOM 树。
  • 重要性:CSSOM 的构建与 DOM 的构建并行进行,二者最终合并生成渲染树。

2.3 构建渲染树

  • 渲染树的构建:将 DOM 树和 CSSOM 树合并,生成一个新的树——渲染树。
  • 特点:渲染树只包含实际会显示的节点(如 display: none 的元素不会被包含),并包含所有必要的样式信息。

2.4 布局(Layout/Reflow)

  • 布局计算:浏览器根据渲染树计算每个节点的几何信息(如位置、尺寸等),称为布局或 reflow。
  • 性能影响:布局计算是耗时操作,频繁的 reflow 可能严重影响页面性能,因此优化 DOM 结构和减少不必要的修改非常重要。

2.5 绘制(Paint)

  • 绘制阶段:浏览器将渲染树中的每个节点转换成实际的屏幕像素。
  • 绘制内容:包括背景、文本、边框、阴影、图片等。
  • 优化建议:尽量使用硬件加速技术,如 CSS 的 transformopacity,避免触发重排。

2.6 合成(Composite)

  • 合成过程:现代浏览器会将页面分成多个图层,每个图层独立绘制,然后合成最终页面。
  • 作用:使得页面局部更新时只重绘变化的部分图层,提高整体性能。
  • 示例:当一个动画仅改变元素的 transform 属性时,浏览器可能只更新该图层而不是整个页面。

3. 优化关键渲染路径的策略

理解了浏览器的渲染流程后,我们可以采取一系列优化措施来提升页面性能:

  • 减少阻塞资源:将关键的 CSS 和 JavaScript 放在页面头部,并使用 asyncdefer 加载非关键脚本。
  • 压缩和合并文件:压缩 HTML、CSS 和 JavaScript 文件,合并资源减少 HTTP 请求次数。
  • 延迟加载:对非首屏内容使用懒加载策略,确保页面首次加载时只加载必要的内容。
  • 利用缓存:合理设置 HTTP 缓存策略(强制缓存、协商缓存),减少重复请求。
  • 简化 DOM 结构:减少 DOM 节点数量,避免深层嵌套,降低布局计算的复杂性。

比如

在开发一个网站,页面上有大量图片和动态内容。可以:

  • 将首页的关键 CSS 和 JavaScript 内联或放在前面,确保首屏快速呈现。
  • 对非首屏图片使用懒加载技术,利用 Intersection Observer API 延迟加载。
  • 使用代码拆分和按需加载策略,将大型模块分离,减少首屏资源的体积。