更新DOM应优先用textContent(安全高效)和innerHTML(需防XSS),避免读写混合触发重排;批量操作用replaceChildren();高频更新用requestAnimationFrame()节流,并借助DevTools定位性能问题。

直接修改 textContent 或 innerHTML 是最常用方式
绝大多数场景下,更新文本内容用 textContent,插入带标签的 HTML 用 innerHTML。前者更快、更安全(自动转义),后者灵活但有 XSS 风险。
常见错误是混用:比如想更新纯文本却用了 innerHTML,导致不必要的 HTML 解析开销;或者对用户输入直接拼接进 innerHTML,引发安全漏洞。
- 更新按钮文字:
button.textContent = "已提交" - 动态渲染列表项(已确保内容可信):
list.innerHTML = items.map(i => `- ${i}
`).join("") - 避免:
el.innerHTML = "—— 应改用" + userInput + ""textContent或createElement+appendChild
批量 DOM 更新要避免反复触发重排(reflow)
连续修改多个元素属性(如 style.color、style.margin)或反复读写 offsetHeight 等布局属性,会强制浏览器同步计算样式和布局,性能急剧下降。
关键原则:读操作集中、写操作集中,中间不穿插“读-写-读”模式。
立即学习“Java免费学习笔记(深入)”;
- ❌ 错误写法:
el.style.color = "red"; console.log(el.offsetHeight); el.style.margin = "10px" - ✅ 推荐写法:先读完所有需要的尺寸,再统一写样式;或用
documentFragment批量构建节点后一次性挂载 - 对大量列表更新,优先考虑虚拟滚动或只更新可视区域节点,而非全量
innerHTML替换
replaceChildren() 比 innerHTML = "" + appendChild() 更干净
清空并替换子节点时,element.replaceChildren(a, b, c) 是现代标准方法,语义明确、性能更好,且不会意外触发事件监听器重绑(相比先 innerHTML = "" 再循环 appendChild)。
注意兼容性:IE 不支持,Safari 15.4+、Chrome 86+、Firefox 76+ 支持。若需兼容旧版,可用 textContent = "" 后再遍历添加,或封装 fallback。
- ✅ 替换全部子节点:
container.replaceChildren(newDiv, newSpan) - ✅ 清空:
container.replaceChildren() - ⚠️ 不要用:
container.innerHTML = ""; container.appendChild(newDiv)—— 多余步骤,且可能丢失原有事件绑定逻辑
用 requestAnimationFrame() 控制高频更新节奏
监听 scroll、resize 或动画帧中频繁更新 DOM 时,不加节流会导致卡顿。比 setTimeout 更精准的方式是 requestAnimationFrame(),它让更新与屏幕刷新率同步。
不是所有更新都需要它,但涉及视觉反馈(如拖拽位置、滚动指示器)时,它是关键优化点。
- ✅ 正确节流滚动更新:
let pending = false; window.addEventListener("scroll", () => { if (!pending) { pending = true; requestAnimationFrame(() => { updateIndicator(); pending = false; }); } }); - ❌ 直接在
scroll里调用el.style.transform = ...—— 可能每秒触发上百次,远超屏幕刷新率 - 注意:不要在
requestAnimationFrame回调里再触发 DOM 读取(如getBoundingClientRect),否则仍可能引发强制同步布局
el.offsetHeight,都可能让前面几十行样式修改立刻执行重排。与其死记规则,不如用 Chrome DevTools 的 Rendering 面板勾选 “Paint flashing” 和 “Layout Shift Regions”,一眼看出哪块在瞎忙。











