
关于
审计和修复动画性能问题,包括布局抖动、合成器属性、滚动关联动效和模糊效果。适用于动画卡顿、过渡掉帧或审查 CSS/JS 动画性能。
name: fixing-motion-performance description: 审计和修复动画性能问题,包括布局抖动、合成器属性、滚动关联动效和模糊效果。当动画卡顿、过渡掉帧或审查 CSS/JS 动画性能时使用。 risk: safe source: community
fixing-motion-performance
修复动画性能问题。
使用方法
-
/fixing-motion-performance在本次对话中对所有 UI 动画工作应用以下约束。 -
/fixing-motion-performance <file>根据以下所有规则审查文件并报告:- 违规项(引用确切的行或代码片段)
- 影响原因(一句话简述)
- 具体修复方案(代码级建议)
除非明确要求,否则不要迁移动画库。在现有技术栈内应用规则。
适用场景
在以下情况下参考这些指南:
- 添加或修改 UI 动画(CSS、WAAPI、Motion、rAF、GSAP)
- 重构卡顿的交互或过渡效果
- 实现滚动关联动效或滚动触发显示
- 对布局、滤镜、遮罩、渐变或 CSS 变量进行动画处理
- 审查使用 will-change、transforms 或测量操作的组件
渲染步骤术语
- composite(合成): transform, opacity
- paint(绘制): color, borders, gradients, masks, images, filters
- layout(布局): size, position, flow, grid, flex
规则分类(按优先级)
| 优先级 | 类别 | 影响程度 | |--------|------|----------| | 1 | 禁止模式 | 严重 | | 2 | 选择机制 | 严重 | | 3 | 测量 | 高 | | 4 | 滚动 | 高 | | 5 | 绘制 | 中高 | | 6 | 图层 | 中 | | 7 | 模糊和滤镜 | 中 | | 8 | 视图过渡 | 低 | | 9 | 工具边界 | 严重 |
快速参考
1. 禁止模式(严重)
- 不要在同一帧内交替进行布局读取和写入
- 不要在大型或重要表面上持续进行布局动画
- 不要通过 scrollTop、scrollY 或 scroll 事件驱动动画
- 没有停止条件的 requestAnimationFrame 循环是禁止的
- 不要混合使用多个各自测量或修改布局的动画系统
2. 选择机制(严重)
- 默认使用 transform 和 opacity 实现动效
- 仅在交互需要时使用 JS 驱动的动画
- 绘制或布局动画仅在小型、隔离的表面上可接受
- 一次性效果比持续动效更容易被接受
- 优先降级技术而非完全移除动效
3. 测量(高)
- 测量一次,然后通过 transform 或 opacity 进行动画
- 在写入之前批量完成所有 DOM 读取
- 不要在动画期间重复读取布局
- 对类布局效果优先使用 FLIP 风格的过渡
- 优先使用批量测量和写入的方法
4. 滚动(高)
- 可用时优先使用 Scroll 或 View Timelines 实现滚动关联动效
- 使用 IntersectionObserver 进行可见性检测和暂停
- 不要轮询滚动位置来驱动动画
- 离屏时暂停或停止动画
- 滚动关联动效不得在大型表面上触发持续的布局或绘制
5. 绘制(中高)
- 触发绘制的动画仅允许在小型、隔离的元素上使用
- 不要在大型容器上对触发绘制的属性进行动画
- 不要对 CSS 变量进行 transform、opacity 或 position 动画
- 不要对继承的 CSS 变量进行动画
- 将动画 CSS 变量限定在局部范围,避免继承
6. 图层(中)
- 合成器动效需要图层提升,不要假设已提升
- 临时且精确地使用 will-change
- 避免过多或过大的提升图层
- 性能敏感时使用工具验证图层行为
7. 模糊和滤镜(中)
- 保持模糊动画较小(<=8px)
- 仅将模糊用于短暂的一次性效果
- 永远不要持续进行模糊动画
- 永远不要在大型表面上进行模糊动画
- 优先使用 opacity 和 translate 而非 blur
8. 视图过渡(低)
- 仅将视图过渡用于导航级别的变化
- 避免在交互密集的 UI 中使用视图过渡
- 需要中断或取消时避免使用视图过渡
- 将尺寸变化视为可能触发布局的操作
9. 工具边界(严重)
- 除非明确要求,否则不要迁移或重写动画库
- 在现有动画系统内应用这些规则
- 永远不要在同一组件内部分迁移 API 或混合风格
常见修复
/* 布局抖动:用 transform 动画代替 width */
/* 修改前 */ .panel { transition: width 0.3s; }
/* 修改后 */ .panel { transition: transform 0.3s; }
/* 滚动关联:用 scroll-timeline 代替 JS */
/* 修改前 */ window.addEventListener('scroll', () => el.style.opacity = scrollY / 500)
/* 修改后 */ .reveal { animation: fade-in linear; animation-timeline: view(); }
// 测量:在写入前批量读取(FLIP)
// 修改前 - 布局抖动
el.style.left = el.getBoundingClientRect().left + 10 + 'px';
// 修改后 - 测量一次,通过 transform 进行动画
const first = el.getBoundingClientRect();
el.c
兼容工具
Claude CodeCursor
标签
前端开发