前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
  • HTTP

    • 基础篇

      • HTTP的前世今生
      • HTTP是什么
      • HTTP世界全览
      • HTTP分层
      • 键入网址到回车发生什么
      • HTTP报文是什么样子的
      • 理解请求方法
      • URI
      • 响应状态码
      • HTTP有哪些特点
      • HTTP优缺点
      • HTTP的实体数据
      • HTTP传输大文件
      • HTTP的连接管理
      • HTTP的重定向
      • HTTP的Cookie机制
      • HTTP的缓存控制
      • HTTP的代理服务
      • HTTP的缓存代理
    • 高级篇

    • 扩展篇

  • 浏览器相关

  • 计算机基础

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

渲染流程(上):HTML、CSS和JavaScript是如何变成页面的|浏览器篇

# 渲染流程(上):HTML、CSS和JavaScript是如何变成页面的

30 秒速记

  • 浏览器接收 HTML、CSS 和 JavaScript,经过渲染模块处理后输出屏幕像素。
  • HTML 提供标签语义与文本内容,CSS 通过选择器和属性决定展示样式,JavaScript 可以修改内容或样式。
  • 渲染流水线按文中所述依次涉及构建 DOM 树、样式计算、布局、分层、绘制、分块、光栅化和合成。
  • 理解每个子阶段时,应分别说明输入、处理过程和输出,避免只背阶段名称。
  • 掌握流水线可以帮助解释开发者工具指标、页面卡顿、动画优化以及强制同步布局等问题;具体内部实现应以对应 Chrome 版本为准。

浏览器会把 HTML、CSS 和 JavaScript 交给渲染模块处理,最终转换成屏幕上的像素。 简单来说,HTML 提供结构和内容,CSS 决定样式,JavaScript 则可以动态修改两者。中间流程可归纳为构建结构与计算样式、确定布局、生成绘制内容,再完成栅格化和合成,因为这几类阶段分别解决“画什么、画在哪、怎么显示”。理解时要关注每个阶段的输入、处理和输出,这比只背阶段名称更有助于排查卡顿、动画和强制同步布局问题;内部细节仍要结合具体 Chrome 版本判断。

在上一篇文章中我们介绍了导航相关的流程,那导航被提交后又会怎么样呢?就进入了渲染阶段。这个阶段很重要,了解其相关流程能让你“看透”页面是如何工作的,有了这些知识,你可以解决一系列相关的问题,比如能熟练使用开发者工具,因为能够理解开发者工具里面大部分项目的含义,能优化页面卡顿问题,使用JavaScript优化动画流程,通过优化样式表来防止强制同步布局,等等。

既然它的功能这么强大,那么今天,我们就来好好聊聊渲染流程。

通常,我们编写好HTML、CSS、JavaScript等文件,经过浏览器就会显示出漂亮的页面(如下图所示),但是你知道它们是如何转化成页面的吗?这背后的原理,估计很多人都答不上来。

从图中可以看出,左边输入的是HTML、CSS、JavaScript数据,这些数据经过中间渲染模块的处理,最终输出为屏幕上的像素。

这中间的渲染模块就是我们今天要讨论的主题。为了能更好地理解下文,你可以先结合下图快速抓住HTML、CSS和JavaScript的含义:

从上图可以看出,HTML的内容是由标记和文本组成。标记也称为标签,每个标签都有它自己的语意,浏览器会根据标签的语意来正确展示HTML内容。比如上面的<p>标签是告诉浏览器在这里的内容需要创建一个新段落,中间的文本就是段落中需要显示的内容

如果需要改变HTML的字体颜色、大小等信息,就需要用到CSS。CSS又称为层叠样式表,是由选择器和属性组成,比如图中的p选择器,它会把HTML里面<p>标签的内容选择出来,然后再把选择器的属性值应用到<p>标签内容上。选择器里面有个color属性,它的值是red,这是告诉渲染引擎把<p>标签的内容显示为红色

至于JavaScript(简称为JS),使用它可以使网页的内容“动”起来,比如上图中,可以通过JavaScript来修改CSS样式值,从而达到修改文本颜色的目的。

搞清楚HTML、CSS和JavaScript的含义后,那么接下来我们就正式开始分析渲染模块了。

由于渲染机制过于复杂,所以渲染模块在执行过程中会被划分为很多子阶段,输入的HTML经过这些子阶段,最后输出像素。我们把这样的一个处理流程叫做渲染流水线,其大致流程如下图所示:

按照渲染的时间顺序,流水线可分为如下几个子阶段:构建DOM树、样式计算、布局阶段、分层、绘制、分块、光栅化和合成。内容比较多,我会用两篇文章来为你详细讲解这各个子阶段。接下来,在介绍每个阶段的过程中,你应该重点关注以下三点内容

  • 开始每个子阶段都有其输入的内容;
  • 然后每个子阶段有其处理过程;
  • 最终每个子阶段会生成输出内容。

理解了这三部分内容,能让你更加清晰地理解每个子阶段。

面试官追问

追问 1线上商品标题文字正确,但颜色和字号都错了,同事据此认定 HTML 解析失败;你会怎样反驳并划定排查范围?
参考回答

仅凭样式错误不能认定 HTML 解析失败,因为 HTML 主要提供标记、语义和文本,颜色与字号由 CSS 规则决定。应先确认目标节点存在,再检查选择器、属性以及 JavaScript 是否动态改写样式;后续仍需结合实际渲染阶段定位。

追问 2你让候选人解释首屏从文件到像素的过程,他只背出“构建 DOM、布局、绘制”,在工程评审里还缺少哪些关键信息?
参考回答

还缺少样式计算、分层、分块、光栅化与合成等流水线关系,也没有交代各阶段的输入、处理和输出。工程判断不能只靠阶段名称,因为定位卡顿时需要知道数据在哪一步发生变化;具体耗时仍须借助开发者工具验证。

追问 3一个静态活动页后来加入 JavaScript 动态改色和动画,负责人认为输入文件没变多,原有渲染分析无需调整,你怎么判断?
参考回答

需要调整,因为 JavaScript 能修改内容或 CSS 样式值,运行时变化可能让渲染流水线再次处理相关数据。应把脚本触发的状态变化纳入观察范围,而不能只分析初始 HTML 和样式表;仅凭材料还不能断定具体哪个阶段最慢。

追问 4线上页面滚动时卡顿,开发者工具里同时出现布局、绘制和合成活动,值班同学直接把问题归因于 CSS 文件过大,你会怎样排查?
参考回答

不能仅凭多个渲染阶段出现就归因于 CSS 文件大小,应先对齐卡顿时间段并查看各阶段的次数和耗时。再结合脚本是否修改样式、页面是否发生几何或视觉变化缩小范围;没有运行数据时,流水线知识只能指导定位,不能替代证据。

追问 5团队准备优化动画,一方只盯 JavaScript 执行时间,另一方只盯最终合成;你会如何建立更完整的分析链路?
参考回答

应沿着输入到像素的流水线检查脚本修改了什么,以及它如何影响样式计算、布局、分层、绘制、分块、光栅化和合成。每一阶段都要明确输入与输出,再用录制数据确认实际瓶颈;不能因某个阶段理论上存在,就假定它必然是主要成本。

# 构建DOM树

30 秒速记

  • 浏览器不会直接以HTML文本驱动页面操作,而是由HTML解析器将其转换成内存中的DOM树。
  • DOM以节点和父子关系组织文档内容,为后续样式计算以及JavaScript访问提供结构基础。
  • DOM与HTML源码含义接近,但前者是运行时对象,可通过document查询和修改。
  • JavaScript修改DOM节点后,页面内容可以随之变化;此时节点只有文档结构,最终外观还要经过样式计算。

构建 DOM 树,就是把浏览器不能直接操作的 HTML 文本,解析成内存中的树状结构。 树中的节点通过父子关系组织页面内容,既为后续样式计算提供结构,也让 JavaScript 能通过 document 查询和修改节点。比如修改某个 p 节点的 innerText 后,页面内容会随之变化。不过此时只确定了文档结构,节点最终长什么样还要经过样式计算。

为什么要构建DOM树呢?这是因为浏览器无法直接理解和使用HTML,所以需要将HTML转换为浏览器能够理解的结构——DOM树。

这里我们还需要简单介绍下什么是树结构,为了更直观地理解,你可以参考下面我画的几个树结构:

从图中可以看出,树这种结构非常像我们现实生活中的“树”,其中每个点我们称为节点,相连的节点称为父子节点。树结构在浏览器中的应用还是比较多的,比如下面我们要介绍的渲染流程,就在频繁地使用树结构。

接下来咱们还是言归正传,来看看DOM树的构建过程,你可以参考下图

从图中可以看出,构建DOM树的输入内容是一个非常简单的HTML文件,然后经由HTML解析器解析,最终输出树状结构的DOM。

为了更加直观地理解DOM树,你可以打开Chrome的“开发者工具”,选择“Console”标签来打开控制台,然后在控制台里面输入“document”后回车,这样你就能看到一个完整的DOM树结构,如下图所示:

图中的document就是DOM结构,你可以看到,DOM和HTML内容几乎是一样的,但是和HTML不同的是,DOM是保存在内存中树状结构,可以通过JavaScript来查询或修改其内容。

那下面就来看看如何通过JavaScript来修改DOM的内容,在控制台中输入:

document.getElementsByTagName("p")[0].innerText = "black"
@前端进阶之旅: 代码已经复制到剪贴板

这行代码的作用是把第一个<p>标签的内容修改为black,具体执行结果你可以参考下图:

从图中可以看出,在执行了一段修改第一个<p>标签的JavaScript代码后,DOM的第一个p节点的内容成功被修改,同时页面中的内容也被修改了

好了,现在我们已经生成DOM树了,但是DOM节点的样式我们依然不知道,要让DOM节点拥有正确的样式,这就需要样式计算了

面试官追问

追问 1运营在控制台执行 document.getElementsByTagName("p")[0].innerText = "black" 后首段立即变化,他说服务器上的 HTML 文件也被改了,你怎么判断?
参考回答

被修改的是浏览器内存中的运行时 DOM 节点,不是服务器保存的原始 HTML 文件。页面会依据新的节点内容呈现变化,但刷新后是否保留取决于资源或应用逻辑是否再次提供该值,不能把当前页面状态等同于源码持久化。

追问 2一个内容页有上千个节点,埋点脚本要修改首个 p 的文本;从构建 DOM 的职责看,这段脚本依赖了什么能力?
参考回答

脚本依赖 DOM 提供的树状、可查询和可修改结构,通过节点 API 定位首个 p 并更新其内容。浏览器先把 HTML 解析为内存中的 DOM,脚本才能执行这类操作;节点更新后的后续渲染成本不由本节材料单独决定。

追问 3服务端返回的 HTML 文本完全相同,但新版页面增加脚本,在加载后重写了多个节点;你还能把抓到的响应正文当作当前页面结构吗?
参考回答

不能,响应正文只是构建初始 DOM 的输入,脚本可在运行时继续查询和修改节点。排查时应同时检查网络响应与开发者工具中的当前 document;两者不一致并不必然表示解析错误,也可能是正常的脚本更新。

追问 4线上按钮能看到文字,却始终没有预期颜色,同事在控制台确认 DOM 节点存在后就停止排查,你会继续看哪里?
参考回答

节点存在只证明 HTML 已形成可用的 DOM 结构,不能证明它已获得正确样式。应继续检查后续样式计算中目标节点匹配了哪些规则及最终计算值;若结构和样式都正确,再沿后续渲染阶段结合工具观察。

追问 5评审中有人建议跳过 DOM,让业务脚本直接修改原始 HTML 字符串以更新页面;这种方案为什么不符合当前运行模型?
参考回答

浏览器需要先把无法直接使用的 HTML 文本解析成可操作的 DOM 树,业务脚本通常查询和修改的是这份内存结构。修改一段脱离文档的字符串不会自动改变当前页面;若重新解析并替换结构,还会引入额外更新范围和状态管理成本。

# 样式计算

← 导航流程:从输入URL到页面展示这中间发生了什么渲染流程(下):HTML、CSS和JavaScript是如何变成页面的 →

fe
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
  • HTTP

    • 基础篇

      • HTTP的前世今生
      • HTTP是什么
      • HTTP世界全览
      • HTTP分层
      • 键入网址到回车发生什么
      • HTTP报文是什么样子的
      • 理解请求方法
      • URI
      • 响应状态码
      • HTTP有哪些特点
      • HTTP优缺点
      • HTTP的实体数据
      • HTTP传输大文件
      • HTTP的连接管理
      • HTTP的重定向
      • HTTP的Cookie机制
      • HTTP的缓存控制
      • HTTP的代理服务
      • HTTP的缓存代理
    • 高级篇

    • 扩展篇

  • 浏览器相关

  • 计算机基础