SSR 送来的 HTML 虽然可见但不能交互——按钮点了没反应,因为还没有事件监听。水合就是让同一段组件代码在浏览器里再跑一遍:框架不重新创建 DOM,而是按虚拟树逐节点匹配已有 HTML,在合适的节点上挂上事件、恢复状态,把静态页面激活。
水合是有成本的:框架要把整棵组件树重新执行一次、收集依赖与事件,页面越复杂耗时越长。常见优化是只水合可见区域( selective hydration)、给非首屏组件加 lazy 标记;React 18 之后还支持流式水合,让脚本解析与水合交错进行减少阻塞。
// 水合的最小模型:服务端 HTML 上挂事件,不重建 DOM // 服务端已产出:<button id="like" data-count="0">赞 0</button> var btn = document.getElementById('like'); var count = Number(btn.dataset.count); // 从 HTML 上恢复初始状态 btn.addEventListener('click', function () { count++; btn.textContent = '赞 ' + count; // 复用已有 DOM 节点 }); // 对比纯客户端渲染:会先 innerHTML 重建整个子树再挂事件 // 水合的关键就是跳过重建、直接接管