适合批量更新元素内容的 DOM 方法是 textContent、setAttribute() 和 DocumentFragment;单个文本用 textContent,批量插入用 DocumentFragment 避免重排重绘。
直接修改 innerHTML 最快,但有安全和性能隐患;真正高效且可控的方式是组合使用 textContent、setAttribute() 和 DocumentFragment。
单个文本更新优先用 textContent,它比 innerHTML 快且不触发 HTML 解析;批量插入多个节点时,DocumentFragment 能避免重复重排重绘。
textContent:仅设纯文本,无 XSS 风险,浏览器跳过 HTML 解析,速度最快innerText:受 CSS 影响(如 display: none 的元素不计入),性能较差,一般不用innerHTML:能插入 HTML,但每次设置都会销毁并重建子节点,触发样式计算和布局,慎用于高频更新DocumentFragment,把所有新节点 append 进去,最后一次性挂到真实 DOM 上直接操作属性比用 setAttribute() 更快,也更语义清晰;类名操作必须用 classList API,而不是拼接字符串。
id、src、href 等标准属性,直接赋值:el.id = "new-id" 或 el.src = url
data-*)或非标准属性,用 el.setAttribute("data-id", "123")
el.classList.add("active")、.remove()、.toggle()、.contains() —— 不要写 el.className += " active",会覆盖已有类el.disabled = true,比 setAttribute("disabled", "") 更可靠innerHTML += ... 是危险写法?它会强制浏览器先序列化当前 HTML(变成字符串),再拼接新内容,最后全部重新解析渲染 —— 既慢又可能意外执行内联脚本或破坏事件监听器。
const container = document.getElementById("list");
// ❌ 危险且低效
container.innerHTML += "核心是减少重排(reflow)和重绘(rep
aint)次数。不要逐个 appendChild,也不要反复读取 offsetHeight 这类触发布局的属性。
document.createDocumentFragment() 收集所有新节点,一次插入template 标签 + content.cloneNode(true) 复用结构container.style.display = "none",更新完再恢复(适用于非动画场景)requestIdleCallback() 分片更新,但多数业务中用 createDocumentFragment 已足够最常被忽略的是:哪怕只改一个文本,也别用 innerHTML;哪怕只加一个 class,也别碰 className 字符串。DOM 操作的“高效”,本质是减少浏览器隐式开销,而不是代码行数少。