contain: paint 能减少长列表重绘,因它切断容器内外绘制关联,使浏览器无需为整个列表重绘;实测1000+条目滚动帧率从20fps升至58–60fps;但需避免用于含绝对定位重叠或依赖 overflow: hidden 裁剪的场景,且 iOS Safari 不支持 contain: strict。
contain属性为什么能减少长列表重绘
浏览器对未被
限制的元素,会默认保留其子树与页面其余部分的布局、样式、绘制关联。滚动长列表时,哪怕只动一屏,浏览器仍可能为整个列表容器做样式计算甚至重绘——尤其当列表项里有
、
或伪类动画时。
加
后,浏览器明确知道:“这个容器内部的绘制不会影响外部,外部变化也不需要重绘它”,于是大幅收缩重绘区域。实测中,1000+ 条目列表滚动帧率从卡顿的 20fps 提升到稳定 58–60fps(iOS Safari 16.4+ / Chrome 115+)。
注意:不是所有场景都适合。如果列表项之间有绝对定位重叠、或依赖父容器
裁剪,
可能导致裁剪失效或定位偏移。
移动端必须用 contain: paint 而不是 strict
等价于
,看似“更彻底”,但在 iOS Safari 上存在已知兼容问题:开启后,某些含
的表头或滚动锚点会失灵;Android Chrome 旧版本(
立即学习
“
前端免费学习笔记(深入)
”;
真实项目中更稳妥的做法是分层控制:
加在滚动容器(如
)上,解决主要重绘压力
若需进一步隔离布局影响(比如列表高度由 JS 动态计算),再单独对每个
加
永远避免在根滚动容器(
或
)上设
,会导致页面级交互响应延迟
contain 和 will-change 冲突时优先选谁
曾被滥用作“性能急救药”,但它会强制提升图层、增加内存开销,且无法被浏览器自动降级。而
是声明式约束,由浏览器按需优化,无副作用。
两者同时存在时,Chrome 会优先尊重
的边界语义,
可能被忽略;Safari 则可能因冲突直接放弃优化。
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
实操建议:
删掉所有
,改用
+
(仅当真有 3D 动画需求)
如果列表项内有频繁动画(如 loading 骨架屏),对动画元素单独加
,而不是整行加
用
对比开启前后的 “Paint” 和 “Layout” 时间块,确认是否真正收敛
兼容性兜底和检测写法
Android WebView 低版本(
)、微信内置 X5 内核(
)不支持
,直接写会静默失效。不能靠
兜底,因为部分安卓浏览器虽识别语法但行为异常。
推荐检测方式:
然后 CSS 中这样写:
关键点:不要用 JavaScript 动态加
,部分低端机 JS 执行时机晚于首帧渲染,起不到优化效果。
真正难处理的是 hybrid 容器里的 webview —— 得配合客户端发版才能升级内核,这时候只能退回到虚拟滚动方案,
不是银弹。
containtransformopacitycontain: paintoverflow: hiddencontain: paintcontain: strictlayout style paint sizeposition: stickycontain: paint.list-wrapper.list-itemcontain: layout paintbody#appcontain: strictwill-change: transformcontain: paintcontainwill-changewill-changecontain: painttransform: translateZ(0)contain: paintchrome://tracingChrome/74X5/6.12contain@supportsif ('contain' in document.documentElement.style) {
document.documentElement.classList.add('has-contain');
}.list-wrapper {
contain: paint;
}
.has-contain .list-wrapper {
contain: paint;
}style.containcontain