template是浏览器原生的离线dom容器,不渲染、不执行脚本、不加载资源;其内容仅存于只读的content属性中,须用clonenode(true)克隆后操作,且需配合documentfragment批量插入以避免重排重绘。

template标签不是“备用div”,它是浏览器原生的离线DOM片段容器
它不渲染、不执行脚本、不加载图片、不触发布局计算——这些不是“优化结果”,而是浏览器在解析阶段就做出的硬性承诺。比如<template><img src="big.jpg"><script>alert(1)</script></template>,页面加载时既不会发HTTP请求,也不会弹窗,DOM树里根本找不到这个<img>节点。
这和<div style="display:none">或<code><script type="text/template"></script>有本质区别:前者仍会加载资源、执行脚本;后者只是纯文本,不经过HTML解析器校验,结构错误(如未闭合标签)只能靠人眼发现。
必须用template.content.cloneNode(true)才能真正复用
template.innerHTML永远是空字符串,直接appendChild(template)或innerHTML += template.innerHTML什么都不会发生——这不是bug,是设计使然。它的内容只存在于content属性中,且是只读的DocumentFragment。
- 不加
true(即cloneNode(false))只克隆空fragment,子节点全丢 - 克隆后
template.content仍保持原样,可无限次调用cloneNode(true) - 直接
appendChild(template.content)只能成功一次,第二次静默失败(fragment已被移走)
它不解决数据绑定,只解决“结构复用”的底层问题
<template></template>里写{{name}}或v-if毫无意义,它不编译、不响应、不追踪变化。所有动态逻辑必须手动处理:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- 填文本用
textContent,不是innerHTML(防XSS) - 设表单值用
value,不是textContent(保留光标位置和输入状态) - 事件监听器必须克隆后重新绑定:
cloned.querySelector('button').addEventListener(...) -
<slot></slot>在普通DOM中被忽略,只在Shadow DOM挂载时生效
批量渲染必须配合DocumentFragment中转
循环里每轮都container.appendChild(cloned),等于让浏览器反复重排重绘。100条可能卡顿,500条基本卡死。
正确做法是:
- 创建中转容器:
const frag = document.createDocumentFragment() - 循环体内:
frag.appendChild(cloned) - 循环结束后,只调一次
container.appendChild(frag)
真正容易被忽略的是:template本身不提供性能保障,克隆+插入的写法不当,照样拖垮页面。它只是把“安全、结构合法、惰性”的原始素材交给你,怎么用,还是得自己想清楚。










