uni-app多端使用Lottie需避开lottie-web,推荐uni-lottie或lottie-miniprogram;JSON须内嵌base64图片;Canvas需手动设DPR宽高并缩放;长动画要控帧率、循环次数及销毁实例。

别用 lottie-web 直接跑在 App 或小程序里——它一执行就报 document is not defined,不是你代码写错了,是环境根本没 document。
uni-app 多端兼容必须用 uni-lottie 或 lottie-miniprogram
原生 lottie-web 依赖 DOM 和 window,而 App 端(iOS/Android)和微信/支付宝小程序运行在 WebView 或自研渲染器中,没有全局 document 对象。强行调 lottie.loadAnimation() 会直接白屏或崩溃。
-
uni-lottie是目前最稳的 uni-app 专用封装,自动处理 Canvas 初始化、DPR 适配、资源加载路径,App/微信/支付宝/H5 全端通,推荐新项目首选 -
lottie-miniprogram更贴近小程序原生逻辑,但要求基础库 ≥ 2.9.0,且需手动管理canvas上下文与 DPR 缩放,适合已有小程序经验的团队 - 若只做 H5,可保留
lottie-web,但必须加平台判断:uni.getSystemInfoSync().platform === 'h5'
JSON 资源必须内嵌或走 base64,禁用外链图片
很多动画 JSON 里含 assets 字段,指向外部 PNG/SVG 图片路径(如 "p": "images/img_0.png")。uni-lottie 和 lottie-miniprogram 均不支持运行时拉取远程图片,会静默失败或显示空白。
- 导出 JSON 时,在 LottieFiles 或 Bodymovin 插件中勾选 “Include images as base64”,让图片转成字符串塞进 JSON
- 若已拿到带外链的 JSON,可用脚本批量把
static/images/下对应图片读取为 base64 并替换字段(工具见 lottie-api CLI:npx lottie-api embed anim.json -o anim-embedded.json) - 确认 JSON 文件体积:含大量图层或高分辨率图片后,单文件超 500KB 就可能触发小程序包体积警告或 App 启动卡顿
Canvas 渲染必须手动设宽高 + DPR 缩放,不能靠 CSS 拉伸
在 uni-lottie 或 lottie-miniprogram 中,如果只写 style="width: 200rpx; height: 200rpx;",动画会模糊、文字锯齿、细线断裂——因为小程序 Canvas 的绘制分辨率(DPR)和 CSS 渲染分辨率是分离的。
- 先用
uni.createSelectorQuery()获取节点真实像素尺寸,再乘以pixelRatio设置canvas.width/canvas.height - 调用
ctx.scale(dpr, dpr)让绘图坐标系对齐物理像素 - 禁止给
<canvas></canvas>设width/height属性(HTML 属性),那会强制缩放画布,导致失真 - 示例关键片段:
const query = uni.createSelectorQuery().in(this); query.select('#lottie-canvas').fields({ node: true, size: true }).exec(res => { const canvas = res[0].node; const ctx = canvas.getContext('2d'); const dpr = uni.getSystemInfoSync().pixelRatio; canvas.width = res[0].width * dpr; canvas.height = res[0].height * dpr; ctx.scale(dpr, dpr); lottie.setup(canvas); // uni-lottie });
长动画 + loop 容易 OOM,App 端要主动控帧率和循环次数
60fps 动画在 iOS/Android WebView 中频繁重绘 Canvas,极易触发内存告警甚至闪退,尤其冷启动时加载多个 Lottie 实例。
- 导出 JSON 时务必勾选 “Optimize for mobile”,或用 CLI 压缩:
npx lottie-api optimize anim.json -o anim-min.json - 避免
loop="true";改用loop="2"或监听animationEnd事件后手动goToAndPlay(0) - App 端播放中可降帧率保流畅:
animation.setSpeed(0.7),比硬设frameRate更可靠 - 页面
onUnload时必须调animation.destroy(),否则 Canvas 引用残留,下次进页更卡
真正难的不是“怎么播出来”,而是“播得稳、不崩、不糊、不卡”。多端 Canvas 渲染差异、DPR 缩放时机、JSON 资源打包方式、内存生命周期管理——这些细节不抠清楚,上线后掉帧和白屏就是随机发生的。



















