Quasar CLI with Webpack - @quasar/app-webpack
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>content_paste
浏览器会自动在 <table> 内部插入 <tbody>,但 Vue 生成的虚拟 DOM 并不包含 <tbody>,这就会导致不匹配。为了确保匹配正确,请在模板中编写符合规范的 HTML。
处理 Hydration 错误
如果你遇到了 hydration 错误(控制台中会出现类似 “Vuejs Error - The client-side rendered virtual DOM tree is not matching server-rendered content” 的提示),可以尝试以下排查步骤:
- 打开 Chrome 开发者工具(F12)
- 加载出现 “the client-side rendered virtual DOM tree…” 警告的页面。
- 在开发者工具的控制台中滚动找到该警告。
- 点击警告信息中指向 vue.runtime.esm.js 的源码位置链接。
- 在该位置设置断点(在源码浏览器中点击行号左侧)。
- 重新触发同样的警告,通常刷新页面即可。如果有多个警告,可以将鼠标悬停在
msg变量上查看具体信息。 - 找到目标警告并在断点处停下后,查看 call stack(调用栈)。点击下一帧中对 “patch” 的调用来打开其源码。将鼠标悬停在 patch 函数中执行行上方约 4 行处的 hydrate 函数调用上,点击链接即可跳转到 hydrate 的源码。
- 在 hydrate 函数中,从开头往下大约 15 行的位置,找到
assertNodeMatch返回false后 return false 的地方,在此设置断点,并移除其他所有断点。 - 再次触发同样的警告。此时断点命中,执行会停在 hydrate 函数中。切换到开发者工具的控制台,分别输入
elm和vnode查看。其中elm是服务器渲染的 DOM 元素,vnode是虚拟 DOM 节点。elm会以 HTML 形式显示,由此你可以定位出错的位置。