document.createDocumentFragment

1. 是什么?

DocumentFragment 是一组子节点的"虚拟存储",并且它没有父标签。节点存放在 DOM 之外,直到被注入 DOM 中。

2. 不使用 DocumentFragment 时的问题

向 <table> 中添加 65 个子节点,对应页面就要回流 65 次,性能很差。

const table = document.getElementById('u-table');
for (let i = 0; i < 13; i++) {
  const tempTr = document.createElement('tr');
  for (let j = 0; j < 5; j++) {
    const tempTd = document.createElement('td');
    tempTr.appendChild(tempTd);
  }
  table.appendChild(tempTr);
}

3. 使用 DocumentFragment 的优化

// 创建一个文档碎片
const fragment = document.createDocumentFragment();

// 把所有单元格塞进 fragment
for (let i = 0; i < 13; i++) {
  const tempTr = document.createElement('tr');
  for (let j = 0; j < 5; j++) {
    const tempTd = document.createElement('td');
    tempTr.appendChild(tempTd);
  }
  fragment.appendChild(tempTr);
}

// 直接把文档碎片塞到 table 里 —— 只触发一次回流
table.appendChild(fragment);

文档碎片不是真实 DOM 树的一部分,插入到 DOM 时仅触发一次重绘 / 回流。

4. 适用场景

  • 批量插入 DOM 节点(表格行、列表项、SVG 元素等)。
  • 离线构建复杂的 DOM 子树后一次性挂载。
  • 性能要求高的列表渲染(配合虚拟列表效果更佳)。

5. 现代替代

// 现代写法:用数组 + appendChild
const trs = [];
for (let i = 0; i < 13; i++) {
  const tr = document.createElement('tr');
  for (let j = 0; j < 5; j++) tr.appendChild(document.createElement('td'));
  trs.push(tr);
}
table.append(...trs); // 现代支持 append 多参数

Element.append() 支持多参数,也可一次性插入多个节点,效果类似 DocumentFragment。

来源整理自:我的有道云笔记