documentfragment 能减少重排,因其操作在内存中不触发渲染树更新,仅最后挂载时重排一次;正确步骤为创建碎片、批量添加节点、一次性挂载。

用 DocumentFragment 实现批量插入,核心是把所有新节点先“攒”在内存里,最后一次性挂到真实 DOM 上——这样能把 N 次重排压成 1 次。
DocumentFragment 为什么能减少重排
浏览器只在节点真正挂载到已渲染的 DOM 树(比如 body 或某个 div#list)时才触发重排。而 document.createElement()、fragment.appendChild() 这些操作全在内存中进行,不碰渲染树,完全不触发重排。
常见误区:以为创建元素就慢;其实卡顿来自反复挂载。逐个 appendChild 到已有容器,等于让浏览器一次次重新算布局;用 fragment 中转,就是把“跑 100 次商场”变成“去 1 次,拎回全部商品”。
正确写法:三步走
✅ 创建碎片 → ✅ 往里加节点 → ✅ 一次挂载
- 调用 document.createDocumentFragment() 获取一个空的文档片段
- 循环中用 createElement 建节点,再用 fragment.appendChild 加进去(不挂 DOM)
- 循环结束后,对目标容器调用 container.appendChild(fragment)
示例:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
const fragment = document.createDocumentFragment();
for (let i = 0; i
const li = document.createElement('li');
li.textContent = `Item ${i}`;
fragment.appendChild(li); // 不触发重排
}
container.appendChild(fragment); // 只这里触发 1 次重排
什么时候必须用,什么时候可不用
需要 DocumentFragment 的典型场景:向一个已经存在于页面中的容器追加多个同级子节点(比如往已有 ul 里加一堆 li)。
如果先建好一个父节点(如 ul),内部所有子节点都在它身上拼完,再整体挂到 body,那这个父节点本身已是“离线组装”,此时 DocumentFragment 不是必需的——但用也无害,逻辑更统一。
⚠️ 真正低效的操作是:
- 直接对已挂载的 ul 循环 appendChild(li)
- 或用 innerHTML += '
- ...
'(每次赋值都会清空重建,开销更大)
搭配使用的其他关键点
光用 fragment 不够,还要避开几个隐性陷阱:
- 别在循环里反复查 DOM:如 document.querySelector 或 offsetHeight,查一次缓存起来
- 读写分离:避免先读 el.offsetHeight 再设 el.style.width,浏览器会立刻强制同步重排
- 优先用 class 切换代替内联样式修改:改 el.className 或 el.classList 比连写 5 行 style.xxx 更安全
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










