比innerHTML快,因其内容为惰性DocumentFragment,不解析、不执行脚本、不触发布局;须用importNode或cloneNode(true)克隆使用,不可直接appendChild,且需手动绑定事件、重置ID、避免与SSR结构冲突。

<template></template> 是当前提升响应式模板渲染效率最直接、浏览器原生支持的手段,但它不是“写了就快”,关键在怎么用、在哪用、怎么避坑。
为什么<template></template>比innerHTML快
每次设置 innerHTML = htmlStr,浏览器都要从字符串重新解析标签、构建节点、计算样式、触发布局;而 <template></template> 的内容是惰性 DocumentFragment,不执行脚本、不加载资源、不参与渲染流程,只等你克隆后插入。
- 必须用
document.importNode(template.content, true)克隆,不能appendChild(template)——否则原节点被移走,第二次调用就空了 -
template.content是DocumentFragment,不能直接querySelector,得先挂载或用querySelectorAll查找 - 模板里写
<script></script>或<style></style>会被忽略;事件监听器必须克隆后手动绑定 - 嵌套超过 3 层时,手拼
document.createElement的 JS 执行时间明显高于克隆template.content
服务端返回 HTML 片段怎么安全注入
动态 fetch 回来的 HTML 字符串如果直接塞进 innerHTML,容易因标签未闭合、属性解析错误或意外执行脚本而出错。
- 服务端返回的必须是纯结构(不含
/),否则插入后会破坏 DOM 树 - 不要用
innerHTML直接赋值整个响应体;应创建临时<template></template>元素,设其innerHTML,再取.content克隆 - 若片段含
id或data-状态,需手动重置(避免 ID 冲突、状态错乱) - IE 完全不支持
<template></template>,如需兼容,fallback 到<script type="text/template"></script>+ 正则提取
和自定义元素配合时容易踩的坑
自定义元素本身不提速,真正起作用的是你在里面封装的逻辑——比如是否复用 <template></template>、是否批量插入、是否控制渲染时机。
立即学习“前端免费学习笔记(深入)”;
- 在
constructor或connectedCallback中用template.content.cloneNode(true)复用结构,跳过字符串解析开销 - 模板里别放内联事件(如
onclick="handle()"),改用this.shadowRoot.addEventListener()绑定,否则克隆后事件丢失 - 如果模板含
<slot></slot>,记得实例化后手动this.appendChild()注入内容,否则 slot 不生效 -
attributeChangedCallback中避免同步触发 layout,多个属性变更应节制合并,在requestAnimationFrame中统一处理
真正容易被忽略的,是 hydration 边界问题:服务端已输出结构,客户端又用 <template></template> 补内容,id、class、data- 属性一旦重复或冲突,React/Vue/Flutter 都可能丢状态或重绘异常——这不是性能问题,是渲染正确性问题。



















