filter: blur() 在旧版浏览器中常由 CPU 处理而非 GPU,导致严重性能问题;CSS.supports 检测通过不等于实际启用 GPU 加速,需结合 Layers 面板确认 Filter Layer;will-change: filter 可能引发图层爆炸和显存耗尽;backdrop-filter 与滚动、sticky 等组合易致帧率骤降;残留的 will-change 或 SVG 滤镜引用会持续占用 GPU 纹理。

因为这些浏览器根本没把 filter: blur() 交给 GPU 处理,而是用 CPU 做逐像素高斯卷积——在 MT6737、Exynos 7870 这类芯片上,blur(4px) 就能让动画从 60fps 掉到 35fps。
旧 WebView 和 Safari 不进 GPU 合成器是常态
Android 4.4–6.0 系统 WebView、iOS Safari 15.4 之前版本,对 blur() 和 drop-shadow() 的处理逻辑是:解析器认得语法,但渲染管线压根不启用 Filter Layout 特性。它不会报错,也不会 fallback,只是静默走 CPU 路径。实测中,blur(1px) 在某些 Android 5.1 WebView 中仍会触发整层重绘,不是“值小就安全”。
关键判断点:
-
CSS.supports('filter', 'blur(1px)')返回true≠ 实际启用 GPU 加速;必须结合 DevTools Layers 面板看有没有生成 “Filter Layer” - iOS Safari 15.4 之前,
backdrop-filter即使写了-webkit-backdrop-filter,只要父容器没设background-color: rgba(255,255,255,0.1),就直接跳过整条声明 - Chrome 80–100 在低端 Android 上,
blur(8px)可能申请 4 倍于元素尺寸的离屏缓冲区,内存带宽吃紧时直接白屏
will-change: filter 是个危险信号
它不能让模糊变快,只告诉浏览器“这个元素的 filter 值可能会变”,从而提前分配合成层和着色器。但在旧版移动端,这反而引发副作用:
立即学习“前端免费学习笔记(深入)”;
- 全局写
* { will-change: filter }会导致图层爆炸,低端机显存迅速耗尽 - 列表项循环渲染时对每个
.item都加该声明,可能生成上百个独立图层,每层占 0.8–1.5MB 显存 - iOS Safari 几乎无视它;某些 Chrome 版本因强制升层,反而加剧文字糊感
- DevTools Layers 面板里可能看不到异常,但 GPU 纹理上传已持续占用带宽
真正卡顿的源头常被忽略
不是你写的那行 filter: blur(6px) 本身有问题,而是它被谁继承、在什么时机触发:
- 父容器加了
filter,子文字节点自动进模糊管线——哪怕你只想模糊背景 -
backdrop-filter用在overflow-y: auto的弹窗里,背后整页 DOM 都要被截、缩、糊、传 - 滚动区域里用了
position: sticky+backdrop-filter,浏览器需反复提取并模糊整个可视区域,帧率跌破 15fps 是常态 - 动画过程中频繁切换
filter值(如blur(0px) → blur(10px) → blur(0px)),会触发图层反复创建销毁
最常被漏掉的一点:你以为移除了 filter 声明就万事大吉,但只要页面里还残留一个未清理的 will-change: filter 或未销毁的 SVG 滤镜引用,GPU 纹理就可能一直挂着。


















