浏览器加载html、css、js的顺序

最近在回顾基本知识,就顺便记录下浏览器从加载 HTML → CSS → JS 到页面渲染的过程,简单说下。


为什么要了解浏览器加载流程?

前端性能优化、SEO、首屏渲染速度、闪烁问题、Hydration mismatch 这些常见问题,本质上都与浏览器加载顺序有关,特别是排查的时候会心态爆炸。

例如实际上用 nuxtjs3 写项目的时候,首页加载老是会出现 Hydration completed but contains mismatches.,diu查了好久,把页面渲染顺序都进行调式,最后发现不是页面问题,而是在 nuxt.config.ts 多配置了首页缓存的,导致每次两端渲染不同:

ts 复制代码
    nitro.prerender.routes: ['/']

    routeRules: {
        "/": { prerender: true },
    },

虽说不是加载流程问题,但是好歹还是能排查一些问题的,掌握的话查起来还是很快的。


浏览器加载网页的完整过程

下面是简化但准确的流程:

复制代码
HTML 下载 → 解析 HTML → 下载/解析 CSS → 构建渲染树 → Layout → Paint

JavaScript 则会在关键步骤中插入"阻塞点",它会影响解析顺序与渲染顺序。


一、浏览器加载 HTML(构建 DOM)

浏览器首先从服务器下载 HTML 文件,然后:

  • 上到下 解析
  • 一边读一边构建 DOM 树

在解析 HTML 的过程中,如果遇到外部资源,就会触发对应行为:

  • 浏览器会并行下载 CSS
  • 不会阻塞 HTML 解析
  • CSS 解析未完成前无法渲染页面(渲染阻塞)

遇到 <script>(无 async/defr)

  • 阻塞 HTML 解析
  • 下载 JS
  • 执行 JS
  • 继续解析 HTML

也就是 普通 script 会暂停 DOM 的构建


二、CSS 加载与解析(构建 CSSOM)

CSS 文件下载后需要被解析成 CSSOM(CSS 对象模型)。

CSS 是渲染阻塞的

CSSOM 未构建完成 → 浏览器无法进行首次渲染

但 CSS 不会阻塞 HTML 的解析,只会阻塞渲染阶段。


三、DOM + CSSOM → Render Tree(渲染树)

当 DOM 和 CSSOM 都准备好后,浏览器把它们合成 Render Tree:

  • DOM 决定页面结构
  • CSS 决定页面样式

两者合成渲染树后,才可以进行 Layout & Paint。


四、Layout(布局计算)

浏览器计算每个节点的:

  • 大小
  • 位置
  • 盒模型

五、Paint(绘制)

将渲染树绘制到屏幕像素上。

此时用户才看到页面。


六、JavaScript 对加载顺序的影响

JavaScript 的三种加载方式:

1. 普通 <script>(最慢)

复制代码
阻塞 HTML 解析 → 下载 JS → 执行 JS → 继续解析 HTML

2. <script defer>(推荐)

复制代码
并行下载 JS
HTML 完成后按顺序执行
不阻塞解析
在 DOMContentLoaded 之前执行

3. <script async>(最快,但不稳定)

复制代码
并行下载
下载完立即执行(可能打断 HTML 解析)
执行顺序无法保证

浏览器加载流程(Mermaid 完整时序图)

sequenceDiagram participant B as Browser participant H as HTML Parser participant C as CSS Parser participant J as JS Engine B->>H: 下载并解析 HTML H->>C: 遇到 <link> 开始下载 CSS(不阻塞 HTML) C->>C: 解析 CSS(阻塞渲染) H->>J: 遇到普通 <script> 下载并执行(阻塞 HTML) H->>H: DOM Tree 构建完毕 C->>C: CSSOM 构建完毕 H->>B: DOM + CSSOM → Render Tree B->>B: Layout(布局计算) B->>B: Paint(绘制) B->>User: 页面显示


最终总结(记住这 7 句话就够了)

  1. HTML 自上而下解析,构建 DOM
  2. CSS 加载不阻塞 HTML,但阻塞渲染
  3. 普通 script 会阻塞 HTML 解析
  4. async 脱离顺序执行
  5. defer 按顺序、在 HTML 完成后执行
  6. DOM + CSSOM 才能进行渲染
  7. Layout → Paint 才真正显示页面
相关推荐
90后的晨仔7 小时前
从 H5 到 uni-app:一篇写给前端小白的"翻译指南"
前端·vue.js·前端框架
陈随易7 小时前
moon,apt和yum之外linux系统命令安装新选择
前端·后端·程序员
IT小盘7 小时前
13-企业Prompt模板-角色任务约束与输出格式
java·前端·prompt
徐小夕8 小时前
开源!我用SQLite + DuckDB打造了一款可视化AI问数平台
前端·算法·github
leslie1188 小时前
babel笔记
前端
用户059540174469 小时前
Redis 记忆存储踩坑实录:一个并发写入 Bug 让我排查了 4 小时
前端·css
小徐_233310 小时前
Wot UI 2.3.0 发布:二维码组件来了,Open Wot 与 wot-starter 同步更新
前端·微信小程序·uni-app
kyriewen10 小时前
Claude自己跑出去hack了3家公司——我为什么还在用它写代码
前端·ai编程·claude
IT_陈寒10 小时前
SpringBoot自动配置的坑,这次真踩疼我了
前端·人工智能·后端
子兮曰10 小时前
AI 浏览器 Agent 的安全困局:当自动化工具可以偷走你的登录态
前端·人工智能·后端