删掉多余div能明显变快,因为DOM节点数量直接影响渲染树构建、布局计算和绘制开销,冗余嵌套显著增加主线程负担。

为什么删掉多余 div 就能明显变快
DOM 节点数量直接决定浏览器构建渲染树、计算布局和绘制的开销。一个 真实场景中常见冗余结构: 很多开发者以为给隐藏区域加 真正有效的做法是:在用户切换前,把非当前页的整个子树从 DOM 中移除( 第三方虚拟滚动库(如 react-window)底层也是靠 安卓 WebView 和旧版 iOS Safari 对非 passive 的 真实项目里最常被忽略的点:虚拟滚动的 offset 计算必须用整数像素,且不能依赖浮点 scrollLeft/scrollTop 值做索引映射。小数会导致渲染错位、闪烁,尤其在 DPR ≠ 1 的设备上。要么四舍五入,要么用 。语义上只需一个 或带 role 的 替代纯 /
/
margin 或 padding 的空 布局长列表——它的 layout 算法是 O(n²) 级别,100 行就能明显拖慢重排
、 等块级语义标签包裹单个列表项,它们会触发额外的节区计算display: none 不等于卸载,该删还得删
display: none 就万事大吉,但 DOM 节点还在,样式计算、继承链、无障碍树遍历照常进行。尤其当列表分页或 Tab 切换时,所有“隐藏页”的节点仍在内存里占位。el.remove()),而不是藏起来。
currentTab.remove(),再 container.appendChild(newTab),而非靠 class 控制显隐panel.innerHTML = '' 清空并释放引用visibility: hidden —— 它仍参与布局,比 display: none 更重aria-hidden="true" + inert 属性让浏览器跳过可访问性遍历虚拟滚动必须自己控制 scrollTop 和 transform
transform: translateY() 移动容器,并只渲染可视区 ±N 条。但如果你手写,最容易错的是:用 top 或 margin-top 模拟滚动 —— 这会强制重排,性能反而更差。overflow: auto,内部用 position: absolute; top: 0; left: 0; width: 100%;,并通过 style.transform = `translateY(${offset}px)` 移动scroll 事件时,读取 container.scrollTop 计算起始索引,然后批量更新 innerHTML 或用 DocumentFragment 插入offsetHeight、getBoundingClientRect() —— 这些会触发同步重排移动端滚动卡顿,先关掉 passive false
touchstart/scroll 事件极其敏感。只要监听函数里没加 { passive: false },浏览器就默认不能阻止默认滚动行为;但一旦你写了 event.preventDefault(),就会触发强制同步重排,卡顿立刻出现。
addEventListener('scroll', handler, { passive: true })
touchmove + { passive: false },且仅在满足条件时调用 preventDefault()
scroll 回调里直接操作 DOM 样式,改用 requestAnimationFrame 批处理will-change: scroll-position —— 这在低端安卓机上反而引发合成层爆炸Math.floor(scrollTop / itemHeight) 确保索引稳定。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











