跳到正文
笔记库
动效3 分钟成长中

给动效做预算:一屏只留一个常驻动画

效果组件是素材,不是风格。真正决定审美的不是用了什么效果,而是拒绝了哪些效果。

我第一次做个人站的时候,几乎每个区块都有一个动效:标题打字、卡片倾斜、光标光斑、背景粒子、列表逐条 fade-in。

上线后自己看了三遍,感受是累。不是"信息太多"的累,是"页面一直在动"的累。

问题不在数量,在于「常驻」

把所有动效按触发方式分两类,问题立刻清楚:

类型例子特征
常驻背景粒子、光标光斑、循环打字你不动它,它也在动
触发式hover、滚动进入、点击展开你不理它,它是静的

常驻动效的代价不在加载,而在注意力的持续占用。人是会一直看移动的东西的,这是生理反应,不是自律问题。

一屏里出现两个常驻动效,读者就无法专心读那一行字。

四条红线

于是我给自己的站点定了四条,写进规划文档当约束用:

第 3 条是最有用的。"承重"的意思是:删掉它,功能会缺损。 进度条承重,因为它告诉读者还剩多少;hover 反馈承重,因为它证明这行能点;背景极光不承重,所以它只能出现一次,在首屏。

落地之后长什么样

位置效果为什么留
首屏背景极光着色器全站唯一常驻动效,滚走即消失
标题一个词循环解密只对一个词,7 秒一次,不整句闪
列表入场位移 8px / 220ms建立节奏,但小到几乎察觉不到"在动"
行 hover纯 CSS 右移 2px0 成本,120ms
效果页Dock / 滚动展开 / 波浪默认静帧,想看的人自己点
工艺页尾滚动背景序列占三屏,只在 /craft,不进首页

位移只有 8px 这个数字是调出来的。试过 24px,节奏感更强,但读者会明确地"看到元素飞进来",注意力被动画本身吃掉了一半。

性能上的三个必做项

  1. WebGL 效果延后挂载:requestIdleCallback 之后才加载着色器模块,不抢首屏 JS。
  2. 减少动效偏好下不加载:prefers-reduced-motion 时直接给静态渐变,不是把速度调成 0.01。
  3. 只动 transform 与 opacity:这两个属性不进布局,也不重绘。
// 降级的判据只有一个,组件不许自己判断
const reduced = usePrefersReducedMotion()
if (reduced) return <StaticGradient />

反过来想

一个更简单的判据:如果把这个动效换成一张静帧,页面会损失什么?

如果答不出来,它就不该存在。这个标准很残酷,但它能过滤掉九成"看起来很酷"的想法——而剩下的那一成,才是审美。

按这条预算做出来的一个完整例子是 滚动背景序列:它必须占三屏、只能出现在一个位置,做的时候还得为它单独算一遍合成亮度。

接着读