动效降级需从设备能力、网络状态、系统偏好三层自动识别并分级响应:硬件指标(如核数、dpr、raf耗时、ua关键词)决定初始动画策略;弱网下禁用非关键动画、延迟触发、优化媒体加载;系统偏好启用时重置css过渡与js行为;canvas掉帧超5秒则降级为css动画+事件映射。

动效降级开关不是加个“关闭动画”按钮就行,而是要从设备能力、网络状态、系统偏好三层自动识别,并在不破坏功能的前提下让动画变轻、变少、甚至换种方式呈现。
用硬件指标做首次分级
页面加载初期就该决定动画基调,不能等 JS 跑起来再判断:
- 读取 navigator.hardwareConcurrency:≤2 核直接切到 30 FPS + 禁用粒子/阴影/多层 save-restore
- 检查 devicePixelRatio ≥ 2 但首帧 RAF 耗时 > 16ms:说明是高分屏低性能机,缩放 Canvas 尺寸至显示尺寸的 0.7 倍,用 CSS scale 补足
- UA 包含 Mi/、HUAWEI MLA-AL10、vivo Y33s 等已知低性能机型关键词时,跳过所有 Canvas 动画初始化,直奔 DOM 动画兜底方案
靠网络信号动态调档
弱网下动画不是卡,而是拖慢关键内容渲染。降级重点不在“停”,而在“不抢资源”:
- 监听 navigator.onLine 变化,离线或弱网(
fetch超时 ≥ 3s)时,禁用轮播自动播放、取消骨架屏循环动画、把 loading spinner 改为静态图标+文字提示 - 对视频类动效(如短剧封面翻转、弹幕入场),改用 preload="metadata" + loading="eager",不预解码帧,只加载关键帧缩略图
- 所有通过
IntersectionObserver触发的动效,在弱网下延迟 500ms 启动,避免滚动时集中触发造成卡顿
尊重系统级动效偏好
用户在系统设置里关掉动画,不是想让页面变死,而是希望交互更干脆:
- 媒体查询必须写对:@media (prefers-reduced-motion: "reduce")(注意英文引号和小写)
- 不止清
animation,还要重置:transition-duration: 0.01s、scroll-behavior: auto、will-change: auto - JS 动画必须同步响应:初始化时读取
window.matchMedia("(prefers-reduced-motion: reduce)").matches,启动前判断,不运行中暂停 - 对依赖过渡维持可访问性的组件(如手风琴菜单),保留最小必要过渡:
[aria-expanded="true"] { transition: max-height 0.1s linear; }
留好无缝切换的退路
Canvas 或 WebGL 动画持续掉帧超 5 秒,就该主动交出控制权:
- 预置轻量 DOM 结构(如
<div class="sprite-move"></div>),用纯 CSS@keyframes实现位移、缩放、淡入 - Canvas 不销毁,改为透明覆盖层,仅捕获点击/触摸事件,坐标映射保持不变
- 通过
getComputedStyle读取 DOM 元素实时位置,反向同步给 Canvas 中需交互的残留元素(如拖拽手柄)











