Hydration
Hydration 在 SSR 和 SSG 场景中的作用,以及它与首屏直出、事件绑定和前后端一致性的关系。
[!info] related notes
Hydration
Hydration 常出现在 SSR 和 SSG 讨论里,因为服务端先给了用户一份可见 HTML,但这份 HTML 还需要被前端框架接管,页面才真正具备完整交互能力。
一句话定义
Hydration 是前端框架在浏览器中复用已有 HTML,并把组件逻辑、事件绑定和状态重新接上的过程。
为什么它会出现
- SSR 和 SSG 会先给浏览器一份已经渲染好的 HTML
- 这份 HTML 让用户更早看到内容
- 但静态 HTML 本身不等于完整交互
- 前端框架还要在客户端恢复组件树和事件系统
它到底在做什么
- 识别服务端已经输出的 DOM
- 建立客户端组件树和这份 DOM 的对应关系
- 绑定事件
- 接管后续更新
在 React 里应该怎么理解它
可以把它先想成:
- 服务端先把首屏 HTML 画出来
- 浏览器先把这份 HTML 显示给用户
- 客户端 React 再启动,把组件逻辑和现有 DOM 接起来
所以 hydration 不是“再渲染一份 HTML”,而是“接管已有 HTML,让它真正活起来”。
一个最常见的体验现象
用户可能先看到内容,但在 hydration 完成前,页面还不一定具备完整交互能力。
这也是为什么:
- 首屏可见不等于可交互
- SSR 页面依然需要下载和执行 JavaScript
- 页面越大,接管成本越高
为什么 hydration 可能成为性能问题
- 首屏虽然更早可见,但客户端仍然要下载并执行 JavaScript
- 页面越大、组件越多,接管成本越高
- 如果服务端输出和客户端首次渲染结果不一致,还可能触发 mismatch
一个最常见的坑
如果客户端第一次渲染想要的结果和服务端输出的 HTML 不一致,就会出现 hydration mismatch。
例如:
- 用了时间戳
- 用了随机值
- 首屏直接依赖浏览器专属 API
- 服务端和客户端拿到的数据不同
这类问题继续看:react-hydration-mismatch
常见误区
- 以为 CSR 默认也需要 hydration
- 以为首屏能看到内容就代表页面已经完全可交互
- 以为 SSR 输出的 HTML 不需要前端框架再参与
- 只关注 HTML 直出,不关注 hydration 的 JavaScript 成本
最短记忆方式
Hydration 就是把已经显示出来的 HTML 重新接上前端框架的生命和交互。
面试要点
来自 hydration-interview-question 的面试视角整理。
一句话回答
Hydration 是客户端接管服务端已输出 HTML 的过程;SSR 和 SSG 只是提前给了可见内容,但页面要真正恢复事件、状态和后续更新能力,仍然需要 hydration。
最稳的回答主线
- SSR 或 SSG 先把 HTML 提前输出,让用户更早看到内容
- 但那时页面不等于已经完全由前端框架接管
- 浏览器还要下载并执行 JavaScript,完成事件绑定和组件树恢复
- 这个接管过程就是 hydration
一个更完整的面试表达
可以这样答:
SSR 或 SSG 只是先把页面内容画出来,但那时用户看到的是“已经显示的 HTML”,不等于前端框架已经接管完成。
浏览器还要继续下载和执行 JavaScript,把组件树、事件绑定和后续更新能力接回去,这个接管过程就是 hydration。
所以 hydration 的核心价值,是让“看得见的页面”变成“真正活起来的页面”。
为什么它经常和性能问题绑在一起
因为 hydration 不是免费的。
即使 SSR 已经把 HTML 提前给了用户,客户端仍然要承担:
- 下载 JS
- 执行 JS
- 恢复组件树
- 绑定事件
如果这部分成本太重,用户就会出现“先看见,后能点”的体验。
面试里容易加分的一句
SSR 优化的是内容直出时间,不是免费省掉客户端执行;如果 hydration 成本很高,页面可能出现“先看到但还不够快能交互”的情况。
常见追问
- 为什么 SSR 页面还会有较大的 JavaScript 体积
- hydration mismatch 是什么
- SSR、SSG 和 hydration 是什么关系
- 怎么理解可见时间和可交互时间的差别
最短记忆方式
SSR 先把页面画出来,hydration 再把它接活。