为什么捐赠
API 浏览器
联系站长
Quasar CLI with Webpack - @quasar/app-webpack
客户端 Hydration(水化)

Hydration(水化)是指客户端的一个过程:Vue 接管服务器发送的静态 HTML,将其转变为能够响应客户端数据变化的动态 DOM。

既然服务器已经渲染好了 HTML 标签,我们当然不希望把它们丢掉再重新创建所有 DOM 元素。我们要做的是"hydrate"(水化)这些静态标签,让它们变得可交互。

WARNING

在开发模式下,Vue 会检查客户端生成的虚拟 DOM 树是否与服务器渲染的 DOM 结构一致。如果不一致,Vue 会放弃 hydration,丢弃现有 DOM 并从头渲染。在生产模式下,为了最大化性能,该检查会被禁用。

Hydration 注意事项

使用 SSR + 客户端 hydration 时,需要注意某些特殊的 HTML 结构可能会被浏览器自动修改。例如,当你在 Vue 模板中写了这样的代码:

<table>
  <tr>
    <td>hi</td>
  </tr>
</table>

浏览器会自动在 <table> 内部插入 <tbody>,但 Vue 生成的虚拟 DOM 并不包含 <tbody>,这就会导致不匹配。为了确保匹配正确,请在模板中编写符合规范的 HTML。

处理 Hydration 错误

如果你遇到了 hydration 错误(控制台中会出现类似 “Vuejs Error - The client-side rendered virtual DOM tree is not matching server-rendered content” 的提示),可以尝试以下排查步骤:

  1. 打开 Chrome 开发者工具(F12)
  2. 加载出现 “the client-side rendered virtual DOM tree…” 警告的页面。
  3. 在开发者工具的控制台中滚动找到该警告。
  4. 点击警告信息中指向 vue.runtime.esm.js 的源码位置链接。
  5. 在该位置设置断点(在源码浏览器中点击行号左侧)。
  6. 重新触发同样的警告,通常刷新页面即可。如果有多个警告,可以将鼠标悬停在 msg 变量上查看具体信息。
  7. 找到目标警告并在断点处停下后,查看 call stack(调用栈)。点击下一帧中对 “patch” 的调用来打开其源码。将鼠标悬停在 patch 函数中执行行上方约 4 行处的 hydrate 函数调用上,点击链接即可跳转到 hydrate 的源码。
  8. 在 hydrate 函数中,从开头往下大约 15 行的位置,找到 assertNodeMatch 返回 false 后 return false 的地方,在此设置断点,并移除其他所有断点。
  9. 再次触发同样的警告。此时断点命中,执行会停在 hydrate 函数中。切换到开发者工具的控制台,分别输入 elmvnode 查看。其中 elm服务器渲染的 DOM 元素vnode虚拟 DOM 节点elm 会以 HTML 形式显示,由此你可以定位出错的位置。