Safari 15–16不支持Web Animations API,应避免用if判断;可行方案为CSS class+transition或requestAnimationFrame手动插值;复杂动画推荐anime.js等适配库;优先使用transform而非top/left以避免强制布局。
旧版 Safari(transform 的 translateZ(0) 触发硬件加速
很多开发者习惯加 transform: translateZ(0) 或 translate3d(0,0,0) 强制开启 GPU 加速,但在 Safari 9–12 中,这反而可能引发闪烁、重绘异常,甚至导致 position: fixed 元素错位。
替代方案更稳妥:
- 优先用
will-change: transform(Safari 9.1+ 支持),但只在动画触发前动态添加,结束后移除,避免持续开销 - 对纯位移动画,直接用
transform: translateX(...)即可,旧 Safari 对 2D transform 的优化已足够 - 避免在
:hover或@media中写translateZ(0)—— Safari 会错误地复用图层,造成视觉残留
requestAnimationFrame 在 Safari 6–9 中的节流与时间戳偏差
Safari 6–9 的 requestAnimationFrame 实现存在两个关键问题:帧率被系统节流(尤其标签页非激活时),且回调参数 timestamp 不是 DOMHighResTimeStamp,而是近似 Date.now() 值,精度低、易跳变。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 不要依赖传入的
timestamp计算 delta —— 改用performance.now()(Safari 8+ 支持)自行采样 - 对关键动画(如拖拽跟随),加兜底逻辑:
if (lastTime === timestamp) timestamp = performance.now() - Safari 6–7 完全不支持
requestAnimationFrame,必须用setTimeout(fn, 16)+ 自测帧率降级(可通过self.__rafFps = 60手动标记环境)
CSS 动画中 @keyframes 的私有前缀早已失效,但 animation 复合属性仍需谨慎
Safari 5.1–6.1 要求 -webkit- 前缀,但 Safari 7+ 已完全支持无前缀 @keyframes 和 animation。真正容易出错的是复合属性写法: