Chrome 新提案:HTML 反杀 JavaScript,声明式局部更新来了
过去十年里,HTML 最值得关注的一次升级。不是新增一个标签,也不是补一个属性,而是 HTML 可能要开始接管一件原本属于 JavaScript 的事:页面局部更新。
以前更新页面有多绕?
一个订单详情页,要更新支付状态。以前基本是这套流程:
服务端查数据库 → 返回 JSON → 前端 fetch() → JS 解析数据 → 查找 DOM → 手动更新页面
const res = await fetch('/api/order/status');
const data = await res.json();
document.querySelector('#status').innerHTML = `
<strong>${data.status}</strong>
<span>${data.time}</span>
`;
为了更新一小块 HTML,却绕了一整圈。数据在服务端,HTML 也可以由服务端生成,最后却要先变成 JSON,再交给 JavaScript 拼回 HTML。
新方式:服务端直接发 HTML patch
Declarative Partial Updates 的思路很直接:页面先返回骨架,慢数据后面再补。
<section>
<h2>订单状态</h2>
<?start name="order-status">
<p>查询中...</p>
<?end>
</section>
浏览器先把"查询中..."渲染出来,用户不用等所有数据准备完。等服务端查完支付状态之后,在同一个 HTML 响应流里继续输出:
<template for="order-status">
<p><strong>已支付</strong></p>
<p>支付时间:10:32</p>
</template>
浏览器解析到 <template for="order-status">,就会自动找到对应的占位区域,把内容替换掉。
核心变化就一句话:
- 以前:服务端 → JSON → JavaScript → DOM
- 现在:服务端 → HTML patch → 浏览器自动更新
它不是多发一次请求
很多人第一反应会想到 SSE、WebSocket、HTTP/2 Server Push、轮询。都不是。
它本质上还是一次普通的 HTML 请求。一个 request,一个 response,HTML 响应体持续流式输出,浏览器边接收边解析边 patch。
服务端先把页面骨架 flush 给浏览器,后面哪个模块数据准备好了,就继续往这个响应里写对应的 HTML 片段。浏览器收到后,自动把内容补到指定区域。
重点不是"实时通信",重点是:HTML 文档本身开始支持后续 patch。
真正狠的:乱序流式更新
真实业务里,一个页面慢,通常不是所有内容都慢,而是几个模块拖后腿。比如一个后台详情页:
- 基础信息:很快
- 支付状态:一般
- 风控结果:较慢
- 操作日志:最慢
以前只有两个选择:要么服务端等全部数据查完再返回(首屏变慢),要么前端拆成多个接口自己维护 loading 状态。
Declarative Partial Updates 给了第三种方式:页面先出来,模块谁先准备好,谁先补上。
<section>
<h2>支付状态</h2>
<?start name="payment"><p>加载中...</p><?end>
</section>
<section>
<h2>风控结果</h2>
<?start name="risk"><p>加载中...</p><?end>
</section>
如果风控先完成,服务端先发 <template for="risk">;支付后完成,再发 <template for="payment">。浏览器会把它们分别 patch 到正确位置。
慢模块不再拖死整页。
会不会成为框架杀手?
前端框架解决的是一整套工程问题:组件组织、状态管理、路由、构建、复用、复杂交互、团队协作。这些不是一个 HTML 提案能直接吃掉的。
Declarative Partial Updates 真正改变的是:过去很多页面局部更新能力,是框架和库在替浏览器补课。服务端明明已经生成了一段 HTML,但浏览器不知道这段 HTML 应该更新到哪里。
现在这个提案想把这条路径缩短:
- HTML 声明更新位置
- template 携带更新内容
- 浏览器原生完成 patch
这不会让复杂前端消失,但会吃掉一部分纯胶水代码——尤其是那些只是为了"把服务端内容塞回页面"的代码。
还有一个已经落地的能力
这不是浏览器第一次把能力还给 HTML。另一个已经落地的能力叫 Declarative Shadow DOM。
以前创建 Shadow DOM 需要写 JavaScript:
element.attachShadow({ mode: 'open' });
现在可以直接写 HTML:
<price-card>
<template shadowrootmode="open">
<style>.price { font-weight: bold; font-size: 20px; }</style>
<slot name="price"></slot>
</template>
<span slot="price">¥199</span>
</price-card>
两个提案的方向一致:
- Declarative Shadow DOM:让组件封装回到 HTML
- Declarative Partial Updates:让局部更新回到 HTML
现状与未来
Declarative Partial Updates 目前仍处在开发者测试阶段,Chrome 可以通过"实验性 Web Platform Features" flag 开启测试。
相关链接:https://developer.chrome.com/blog/declarative-partial-updates?hl=zh-cn
未来趋势:浏览器平台一定会把一部分框架层能力,下沉到 HTML 标准里。HTML 正在重新变强。