document.createDocumentFragment作为不占DOM树的容器,先将多个新节点在内存中组装,再一次性挂载到真实节点,使渲染引擎只触发一次布局和绘制,有效避免循环插入导致的多次重排重绘。该方法适合动态生成列表等批量操作,但框架已内置优化,超大量节点需搭配虚拟滚动。
在 DOM 批量操作中,有一个容易被忽视的细节:浏览器渲染的瓶颈,往往不在于节点本身的复杂度,而在于向页面中插入的次数。如果能将几十上百次插入压缩为一次提交,性能将显著提升——document.createDocumentFragment 正是为此而生的工具。

长期稳定更新的攒劲资源: >>>点此立即查看<<<
其核心思路是:先在内存中组装好所有待新增的节点,然后一次性插入真实 DOM。这样渲染引擎只被触发一次,避免了反复的重排与重绘。
DocumentFragment 是一个“不占位”的容器,不归属于主 DOM 树,因此不会触发样式计算或布局。向其中添加子节点时,浏览器不会做任何渲染操作,直到最后将整个 fragment 挂载到真实 DOM 节点上,才触发一次 layout 和一次 paint。
如果直接循环 appendChild 到页面元素上,情况则完全不同:每插入一个节点,只要影响几何尺寸(如块级元素、flex 项、浮动元素等),浏览器都可能被迫进行同步布局计算,进而反复触发重排。当节点数量较多时,性能差距肉眼可见。
以下是最通用且安全的模式,适用于动态生成列表、表格行、卡片组等场景:
document.createDocumentFragment() 创建一个空片段document.createElement 或 template.content.cloneNode(true))append 或 appendChild 添加到 fragment 上(注意:fragment 支持 append() 和 appendChild(),但不支持 innerHTML)container.append(fragment))一个简洁明了的示例:
const fragment = document.createDocumentFragment();
const data = ['苹果', '香蕉', '橙子'];
data.forEach(text => {
const li = document.createElement('li');
li.textContent = text;
fragment.appendChild(li); // 仅操作 fragment,无渲染
});
// 一次性插入
document.getElementById('list').appendChild(fragment);
整个过程没有多余的渲染动作。
当插入结构较复杂时(如多层嵌套、带属性、预留事件绑定),搭配 会更加方便。 天生惰性,内容不会被解析或执行,非常适合作为模板容器。
template.content.cloneNode(true) 复制一份独立副本DocumentFragment 在主流浏览器中已稳定支持多年,仍是 DOM 批量插入的黄金标准。但以下几点值得注意:
requestIdleCallback 控制节奏,否则仍可能出现卡顿innerHTML += ... 或循环设置 innerHTML 的操作,它们会反复销毁和重建子树,性能比 fragment 慢数倍,且存在安全风险fragment 并非万能银弹,它只是一种将“多次小更新”压缩为“一次大更新”的务实手段。但当插入操作超过三五个节点时,其带来的性能差异已值得认真考虑。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述