5月30日 23:22

Lottie JSON 文件里每个字段到底表示什么?

Lottie JSON 可以理解成一份“动画说明书”:顶层描述画布和时间轴,layers 描述图层,ks 描述变换属性,shapes 描述矢量形状,assets 描述图片或预合成资源。真正排查问题时,不需要背完整规范,但要能看懂几个关键字段,否则遇到动画不显示、颜色改不了、体积异常时只能反复让设计重新导出。

顶层字段先看时间和画布

常见顶层字段包括 vfripopwhassetslayersfr 是帧率,ip/op 是起止帧,动画时长通常可以用 (op - ip) / fr 估算。w/h 是设计画布,不等于组件最终显示尺寸,但会影响缩放比例和裁切判断。

json
{ "v": "5.10.2", "fr": 30, "ip": 0, "op": 90, "w": 375, "h": 240, "assets": [], "layers": [] }

layers 是排查的入口

layers 数组决定动画由哪些图层组成。ty 表示图层类型,常见的 4 是形状图层,2 是图片图层,0 是预合成,1 是文本。每个图层通常有 ip/op 控制它何时出现,ks 控制位置、缩放、旋转和透明度。遇到某一段动画消失,先看对应图层的起止帧和透明度,不要急着怀疑播放器。

json
{ "ty": 4, "nm": "check-icon", "ip": 0, "op": 60, "ks": { "p": { "a": 0, "k": [120, 80, 0] }, "s": { "a": 0, "k": [100, 100, 100] }, "o": { "a": 1, "k": [{ "t": 0, "s": [0] }, { "t": 10, "s": [100] }] } } }

shapes 和 assets 决定复杂度

形状图层里的 shapes 会包含路径、填充、描边、组和变换。路径点越多、遮罩越多、渐变越复杂,运行时计算越重。assets 则存图片、预合成等资源,图片路径通常由 up 拼出来。生产环境要确认这些资源能被打包或上传到 CDN,否则 JSON 正常,动画却缺图。

如果要做自动检查,可以先抽取几个字段,统计图层数量、图片数量和关键帧属性数量。这个脚本不替代真机测试,但能在代码评审阶段拦下一部分明显过重的动画。

js
function inspectLottie(data) { return { frameRate: data.fr, duration: (data.op - data.ip) / data.fr, layers: data.layers?.length ?? 0, assets: data.assets?.length ?? 0 }; }

不要把 JSON 当成稳定业务协议

虽然 Lottie JSON 是文本格式,但它首先是动画导出产物,不适合让业务代码深度依赖内部层级。比如今天图层叫 button-bg,设计明天合并预合成后路径就变了,客户端按 keypath 改色可能立刻失效。更稳的方式是只读取少量稳定元信息,把主题色、文案、播放区间这类业务配置放在自己的配置文件里。

排查线上问题时也要保留原始 JSON 和压缩后 JSON。压缩工具可能会改字段顺序、删除名称或合并路径,体积变小了,但可调试性会下降。团队如果需要运行时换色或按图层埋点,就不要在构建阶段把所有 nm 字段都删掉。

追问

为什么同一个 Lottie JSON 在不同端表现不一致?

因为 Lottie 是规范加运行时实现,不是所有 AE 能做出的效果都能被各端完整支持。Web、iOS、Android 对遮罩、表达式、渐变、文本和某些混合模式的支持存在差异。取舍上,跨端业务动画应少用高级特效,多用基础形状和透明度变化。踩坑最多的是设计在 AE 里看着正常,导出后某端把效果直接忽略了。

ks 里的 a: 0a: 1 有什么区别?

a: 0 表示这个属性是静态值,k 里直接放当前值;a: 1 表示它有关键帧,k 会变成关键帧数组。排查性能时,有关键帧的属性越多,运行时插值计算越多。边界是关键帧不是坏事,动画本来就靠它,只是不要让每个小装饰都做复杂路径变形。读 JSON 时先看 p/s/r/o 这些变换属性,效率最高。

修改 JSON 里的颜色安全吗?

简单填充色通常可以改,比如 fl.c.k 里的 RGBA 数组,但并不总是安全。颜色可能被渐变、透明度、预合成或命名层级影响,直接全局替换很容易误伤。更稳的做法是让设计给关键图层命名,再在运行时用 keypath 或导出多套主题文件。取舍是动态换色更灵活,但对图层命名和测试要求更高。

图片资源应该内联 base64 还是外部文件?

内联 base64 部署简单,少一次资源路径配置,但会让 JSON 变大,也让缓存粒度变差。外部图片更适合 CDN、WebP 压缩和多动画复用,但需要处理路径、打包和离线缓存。移动端项目通常更推荐把图片作为本地资源随包发布,Web 项目则看首屏策略和缓存命中率。边界是很小且只用一次的图标可以内联,大图和复用资源不要内联。

如何快速判断一个 JSON 是否可能有性能问题?

先看文件体积、layers 数量、路径点数量、是否有大量 masksPropertiesef 和图片资源。再估算时长和帧率,长动画加 60fps 通常要谨慎。这个判断不是最终结论,但能帮助你决定是先找设计减图层,还是先改客户端播放策略。踩坑是只看压缩后大小,忽略未压缩 JSON 在解析时仍然很重。

标签:Lottie