HTML本身没有数组,优化重点是JavaScript操作DOM集合时的性能:用扩展运算符转NodeList为数组,批量更新避免重排,读写分离,用textContent替代innerHTML,数据驱动模板渲染。HTML 本身没有数组,所谓“HTML 数组优化”是常见误解——你真正要优化的,是 **用 JavaScript 操作 HTML 元素集合(如 NodeList、HTMLCollection)时的性能表现**。直接把
document.querySelectorAll 返回值当数组用、在循环里反复调用 getElementById、或对大量 li 逐个 innerHTML = ...,都会触发重排、回流或 DOM 构建开销。下面直奔实操重点:NodeList 不是 Array,它没有 map、filter、forEach(部分浏览器支持但不可靠),强行用会报 TypeError: NodeList is not a function 或静默失败。
[...document.querySelectorAll('.item')] —— 简洁、可读、现代浏览器全支持Array.from(document.querySelectorAll('.item')) —— 显式、语义清晰、支持 map 回调Array.prototype.slice.call(...) —— 冗长、易错、已过时Array.from 处理实时集合(如 getElementsByClassName),它会冻结快照;而 querySelectorAll 本身就是静态的,没问题典型场景:遍历 500 个 div.item,每个都设 textContent 或 className。浏览器每改一次就可能触发样式计算 → 布局 → 绘制,500 次就是 500 次潜在重排。
classList 替代 className = 'a b c' —— 避免字符串拼接和全量重写DocumentFragment 缓存新节点,最后一次性 append 到真实 DOMoffsetHeight 再修改,把所有读操作放前面,所有写操作放后面,防止强制同步布局textContent 而非 innerHTML —— 后者会重新解析 HTML,更慢且有 XSS 风险不是“快多少”,而是“可控性高得多”。硬编码 100 个 <li>...</li> 的 HTML,维护成本爆炸,且无法按条件过滤、排序、分页。
const items = [{id: 1, name: 'A'}, {id: 2, name: 'B'}]
map 生成字符串,再一次性赋给 innerHTML:listEl.innerHTML = items.map(i => `<li data-id="${i.id}">${i.name}</li>`).join('')
data- 属性存结构化数据,后续 JS 可直接读取,不用再 parse 文本在绝大多数实际场景中,差异可以忽略;但极端数量(>10k 元素)下,传统 for 仍略胜一筹,因为无函数调用开销、无闭包创建。
立即学习“前端免费学习笔记(深入)”;
items.forEach(item => item.classList.add('active')) 更直观for 或 for...of
for...of 对 NodeList 支持良好,且语法干净,是折中优选:for (const el of document.querySelectorAll('.item')) { ... }
offsetTop、clientWidth,或连续写 style.color、style.margin,都在悄悄拖慢页面。把读写分开、批量提交、用 class 控制状态——这些比纠结用不用 Array.from 重要得多。