删掉 -webkit-overflow-scrolling: touch 更流畅,因该属性在 Chrome 63+ 和 Safari 15.4+ 已废弃,残留使用会强制降级旧滚动引擎,导致惯性失效、touchmove 阻塞主线程。

直接删掉 -webkit-overflow-scrolling: touch,它不是“没加才卡”,而是“加了反而卡”——Chrome 63+ 和 Safari 15.4+ 已废弃该属性,残留使用会强制降级到旧滚动引擎,惯性失效、touchmove 阻塞主线程。
为什么删掉 -webkit-overflow-scrolling: touch 反而更流畅
这个声明在现代浏览器里已成“反模式”:它不触发硬件加速,只唤醒旧版滚动线程,导致 iOS 惯性滚动丢失、Android 上 touchmove 同步阻塞。DevTools Elements 面板搜一下,只要存在就删;还要检查 JS 是否动态注入(比如某些 UI 库初始化时偷偷加上)。
- 父容器没设
height或max-height?子元素overflow-y: scroll就无效,滚动区域根本没被截断 - 滚动容器用了
transform、opacity或filter的子元素?WebKit 会无序升层,打断滚动线程 - 写了
overflow-y: scroll而非overflow-y: auto?iOS Safari 会为未溢出内容也强占合成层资源
will-change: transform 别乱加,尤其别加给列表项
给每个 .item 加 will-change: transform 是典型翻车操作:一屏 10 个,滚动中常驻 20+ 个,等于塞给 GPU 20 多个图层。中低端安卓机显存吃紧,帧率直接掉到 20fps 以下。
- 只对真实承载位移的容器设,比如
.scroll-content,且必须配真实transform: translateY()或translateZ(0) - 绝对禁止写
.item { will-change: transform; }这类全局 CSS 规则 - 用 Chrome DevTools → Layers 面板确认图层数:稳定在 3~5 层为佳,超过 8 层立刻排查
-
will-change: scroll-position在 iOS Safari 完全无效,别填
滚动监听器不加 { passive: true } 就等于放弃流畅度
哪怕只写了一行 window.addEventListener('scroll', handler),iOS 上滚动帧率也可能从 60fps 掉到 20fps——因为默认 passive 是 false,浏览器必须等 JS 执行完才能继续滚动。
立即学习“前端免费学习笔记(深入)”;
- 所有滚动监听必须显式传
{ passive: true },否则 Chrome/Safari 都会警告并降级 - 需要阻止默认行为(如下拉刷新)?改用
touchstart+preventDefault(),别在scroll里调 - 避免在
scroll回调里读取scrollTop、getBoundingClientRect()或写element.style.xxx——这会强制同步回流(layout thrashing) - 用
IntersectionObserver替代实时滚动计算(比如“滚动到某位置显示按钮”)
真正卡顿的根源往往不在渲染层,而在主线程被拖住或布局反复重算;will-change 是修水管,虚拟滚动才是换管道——但前提是先确保你没在滚动容器上同时套着 border-radius + overflow: hidden 这种组合,它会让所有硬件加速失效。


















