DocumentFragment 用于离线批量插入节点以避免频繁重排重绘;它是轻量级文档片段,操作不触发布局计算,仅一次挂载即可高效插入全部子节点。

用 DocumentFragment 批量插入节点,核心是“先离线组装,再一次性挂载”,避免频繁操作真实 DOM 导致的重排重绘。
为什么用 DocumentFragment?
直接循环调用 appendChild 插入多个节点时,每次都会触发浏览器布局计算(即使不可见),性能较差。而 DocumentFragment 是轻量级的文档片段,不绑定到页面,操作它不会引发重排;最后只需一次 appendChild 或 append,就能把所有子节点高效插入目标容器。
基本用法:创建、添加、插入
步骤很直接:
- 用
document.createDocumentFragment()创建一个空片段 - 用常规方法(如
appendChild、append、innerHTML)往片段里添加元素或文本 - 把整个片段一次性插入到目标父节点中(片段插入后自动清空,不可复用)
示例:批量创建 100 个列表项
立即学习“Java免费学习笔记(深入)”;
const frag = document.createDocumentFragment();
const ul = document.getElementById('myList');
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i + 1}`;
frag.appendChild(li); // 添加到片段,不触发渲染
}
ul.appendChild(frag); // 仅这一次触发 DOM 更新
配合 innerHTML 或模板字符串更简洁
如果内容是结构化 HTML 字符串,可先设 frag.innerHTML(注意:DocumentFragment 本身不支持 innerHTML,但可以借助临时元素中转):
const frag = document.createDocumentFragment();
const temp = document.createElement('div');
temp.innerHTML = Array.from({ length: 100 }, (_, i) =>
`<li>Item ${i + 1}</li>`
).join('');
// 把 temp 的子节点移入 frag
while (temp.firstChild) {
frag.appendChild(temp.firstChild);
}
document.getElementById('myList').appendChild(frag);
或者更现代写法(兼容性稍好):
const frag = document.createDocumentFragment();
const html = Array.from({ length: 100 }, (_, i) =>
`<li>Item ${i + 1}</li>`
).join('');
const temp = document.createElement('template');
temp.innerHTML = html;
frag.append(...temp.content.childNodes);
document.getElementById('myList').append(frag);
注意点和常见误区
片段只能插入一次:插入后自动清空,再次 append 不会报错但什么也不发生。
不能用 querySelector 直接查片段:需先挂载或改用 temp.content.querySelector(搭配 <template>)。
与 createDocumentFragment() 等价的现代替代? 目前没有完全等效的原生新 API,但 <template> 元素配合 content 属性功能高度重叠,且支持 innerHTML,实际项目中常混用。


















