必须删除 -webkit-overflow-scrolling: touch,因其在 ios 13+/chrome 63+ 中已废弃,会触发旧滚动引擎导致惯性失效、事件阻塞、内存泄漏及图层爆炸;滚动容器需设明确高度,内容应避免阴影/圆角/透明度动画引发重绘,滚动监听器须加 passive: true。

直接删掉 -webkit-overflow-scrolling: touch,它已不是“优化项”,而是现代项目的故障源。
为什么必须删除 -webkit-overflow-scrolling: touch
这个属性在 iOS 13+ 和 Chrome 63+ 中已被彻底废弃,但很多项目仍保留它——结果不是“没效果”,而是触发浏览器降级逻辑:强制启用旧滚动引擎,导致惯性滚动失效、scrollTop 不更新、touchmove 被阻塞、甚至整个容器卡死不动。DevTools 里搜到它,就该立刻删。
- 它会创建无法释放的独立图层,引发内存泄漏
- 它破坏事件流,让下拉刷新、手势识别等逻辑失灵
- 它和
transform/opacity子元素叠加时,极易触发图层爆炸(Layer Explosion)
滚动容器必须有明确高度(height 或 max-height)
没有显式高度,浏览器无法确定滚动范围,会退化为“重排驱动滚动”,主线程反复计算 layout,帧率直接跌破 30fps。这不是兼容性问题,是渲染机制硬约束。
- 错误写法:
.list { overflow-y: auto; }(无height/max-height) - 推荐写法:
.list { height: 100vh; overflow-y: auto; } - 更健壮写法(Flex):
.container { display: flex; flex-direction: column; height: 100vh; } .list { flex: 1; overflow-y: auto; }
滚动区域内容要避免触发全量重绘
阴影、圆角、透明度动画在滚动中会强制每帧重绘(Paint),尤其在中低端 Android 上,一帧耗时飙升。iOS 对这些优化较好,但多层叠加后仍会掉帧。
-
box-shadow:改用伪元素 + 半透色背景,或换outline(不参与重排重绘) -
opacity动画:禁用,改用transform: translateZ(0)+will-change: transform(仅限真位移元素) -
border-radius> 4px 且配渐变背景时:优先用 SVG 或裁剪图替代
滚动监听器必须加 passive: true
默认 passive: false 会让 iOS Safari 和 Chrome 强制等待 JS 执行完才继续滚动,哪怕监听器里只有一行空语句,也会让帧率从 60fps 掉到 20fps。
- 正确写法:
window.addEventListener('scroll', handler, { passive: true }); - 需要阻止默认行为(如下拉刷新)时,不要在
scroll里调preventDefault(),改用touchstart捕获并立即调用 - 所有读取布局的 API(如
getBoundingClientRect())必须节流,并包裹在requestIdleCallback中
真正难处理的不是“怎么让它动起来”,而是“怎么让它动得稳定”——滚动卡顿往往藏在 Paint 和 Layout 耗时里,而不是 JS 执行时间上。真机调试时,先打开 DevTools 的 Performance 面板看帧详情,再动手改 CSS。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











