Code前端首页关于Code前端联系我们

Vue3中怎么用Lottie实现流畅又不占资源的动效?踩过的坑全说清楚

terry 1小时前 阅读数 22 #Vue

Vue3搭配Lottie,比手写CSS/JS动效强在哪?

以前做项目里的加载页、点赞动效、节日主题Banner,要么靠设计师切几十帧PNG/GIF,要么自己写几百行贝塞尔曲线、requestAnimationFrame回调,要么套套现成的CSS动画库——要么是动效还原度差得离谱,要么是代码写得头大还容易卡,要么是GIF体积大到加载半天、颜色有断层。 直到后来发现Lottie,配合Vue3的组件化、Composition API,真的是把前端动效门槛拉到了地板,简单说,Lottie就是一个能直接解析After Effects(AE)导出的JSON动画文件的库,设计师在AE里做什么动效、加什么遮罩粒子、搞什么缓动,前端直接扔进去就能1:1还原,不用写一行复杂的动效逻辑,而且JSON文件通常只有几十KB到几百KB,同效果下比GIF小80%以上,还支持透明背景、逐帧暂停/播放、色彩替换、事件监听这些高级操作。 现在主流的Vue3 Lottie库有两个,一个是官方社区维护的vue3-lottie,另一个是Airbnb Lottie官方提供的lottie-web的Vue3封装,后面会对比两个库的区别,新手推荐先上手vue3-lottie,更贴合Vue3的写法。

新手第一步:Vue3 Lottie的基础安装和调用流程

先讲最常用的vue3-lottie吧,这个库封装得特别顺,对Composition API和Options API都友好,甚至连TypeScript的类型支持都做得挺全的。

先装库和依赖

不管是用npm、yarn还是pnpm,一行命令就能搞定,不用单独装lottie-web,vue3-lottie已经内置了,但要注意Vue的版本必须是3.2及以上,太低的话可能会有响应式API不兼容的问题。 安装好之后,怎么用呢?有全局引入和局部引入两种方式,一般推荐局部引入,减少打包体积,毕竟不是每个页面都要用到动效。

拿到JSON文件后,要先“验验货”

很多时候拿到设计师的JSON动画,要么是用了AE里不支持的插件(比如部分粒子插件),要么是导出的时候没选对插件参数,导致前端渲染不出来或者效果失真,这个时候可以先用LottieFiles的在线预览工具先看一下,没问题再用到项目里。 验完货之后,把JSON文件放到项目里——可以放在public文件夹下,通过绝对路径引用;也可以放在src/assets文件夹下,通过ES6的import引入,这里有个小细节:如果放在public文件夹下,路径要注意是相对于项目根目录的;如果放在src/assets下,直接import就行,不过打包的时候JSON文件会被压缩,体积更小。

写个简单的加载页动效试试手

先上局部引入的Composition API写法,这应该是现在Vue3开发者用得最多的,首先从vue3-lottie里引入Lottie组件,然后引入JSON文件,再定义一些基本的参数:比如autoplay(自动播放)、loop(循环播放)、renderer(渲染器,有canvas、svg、html三个可选,后面性能优化会讲怎么选)。 把Lottie组件放到模板里,绑定好参数就行,是不是比写CSS动画快多了?如果想换动效,直接换JSON文件就行,不用改一行代码。 Options API的写法其实也差不多,就是把变量放到data里,组件放到components里注册一下,这里就不单独贴代码了,官方文档里也有。

核心坑点:Vue3 Lottie常见问题怎么解决?

上手是简单,但真要用到生产环境里,踩坑是难免的,我整理了几个我自己和身边朋友踩过最多的坑,每个都有具体的解决方案。

坑1:动效渲染出来是空白?

这绝对是最常见的问题,没有之一,先别急着骂设计师,按照下面的步骤排查: 第一步,先查JSON文件是不是真的能用——就是刚才说的用在线预览工具看; 第二步,查路径是不是错了——如果是public文件夹下的,路径前面有没有加/?如果是src/assets下的,import的时候有没有加后缀名.json?还有,用Vite的话,JSON文件可以直接import,但如果文件名里有空格或者特殊字符,最好换成下划线; 第三步,查Vue3版本是不是够3.2——刚才也说了,太低的话不行; 第四步,查是不是用了SSR(服务端渲染)?比如用Nuxt3的话,直接全局引入vue3-lottie会报错,因为SSR环境下没有window对象,这个时候要把组件包裹在标签里,或者用动态引入的方式,等浏览器环境加载好再渲染。

坑2:动效颜色不对,或者想动态换主题色怎么办?

设计师导出JSON的时候,可能用了固定的颜色,但有时候项目里有亮/暗双主题,或者想让用户自定义颜色,这个时候直接改JSON文件肯定不行——太麻烦了,而且下次设计师更新JSON又要改。 这个时候就用到vue3-lottie里的colorFilters或者tintColor参数了,tintColor是全局染色,比如把整个动效染成红色;colorFilters可以单独改某个图层的颜色,不过需要知道图层的索引或者名字,这个可以让设计师导出的时候把关键图层标好,或者用LottieFiles的在线编辑器看一下图层的结构。 哦对了,用lottie-web的话,还有更强大的API,比如可以通过DOM操作或者canvas操作改颜色,但新手还是推荐用vue3-lottie的封装参数,更简单。

坑3:动效突然变得一卡一卡的?

这个问题通常出现在循环播放的长动效里,或者是多个动效同时加载的时候,后面性能优化会详细讲,但先讲几个快速解决的小技巧: 第一个,检查渲染器是不是选对了——比如动效里有很多粒子或者遮罩,用canvas渲染会比svg快;如果动效比较简单,用svg渲染兼容性更好,而且可以加CSS动画的过渡; 第二个,检查是不是有内存泄漏——比如组件销毁的时候,没有销毁Lottie实例,虽然vue3-lottie已经做了自动销毁,但有时候用了自定义的lottie-web实例,或者用了keep-alive缓存组件,可能需要手动销毁; 第三个,检查JSON文件是不是太大了——如果动效里有太多的矢量图层或者关键帧,可以让设计师精简一下,比如把重复的图层合并,把非关键的关键帧去掉。

坑4:用Nuxt3的时候一直报错?

刚才提了一点SSR的问题,再详细说一下Nuxt3的情况,Nuxt3是现在Vue3 SSR最火的框架了,很多新手用的时候都会踩这个坑。 解决方式有两个:第一个是用Nuxt3官方提供的标签,把Lottie组件包裹起来;第二个是用动态引入的方式,并且加上client-only的标记, const Lottie = defineAsyncComponent(() => import('vue3-lottie').then((m) => m.LottieAnimation) ) 这样Nuxt3就只会在浏览器端加载和渲染这个组件,不会在服务端报错了。

进阶优化:让Vue3 Lottie动效更流畅、更省资源

刚才解决了坑,但要用到生产环境里,性能优化是必须的,毕竟现在用户对页面加载速度和流畅度的要求越来越高了。

选对渲染器:canvas vs svg vs html

刚才提过,Lottie有三个渲染器,每个都有自己的优缺点,要根据动效的复杂程度和项目的需求来选:

  • canvas渲染器:适合复杂的动效,比如有很多粒子、遮罩、关键帧的动效,渲染速度快,性能好,但不支持CSS动画的过渡,也不支持DOM操作,色彩替换的话只能用Lottie的API;
  • svg渲染器:适合简单的动效,比如加载页的小图标、点赞动效,兼容性好,支持透明背景,支持CSS动画的过渡,也支持DOM操作(比如可以给某个图层加hover效果),但复杂动效会比较卡;
  • html渲染器:现在用得比较少了,性能不如前两个,主要是为了兼容一些老的浏览器,现在基本不用了。

    按需加载JSON文件

    如果项目里有很多Lottie动效,比如首页有节日主题Banner,产品页有交互反馈动效, loading页有加载动效,不要一开始就把所有JSON文件都加载进来,那样会拖慢首页的加载速度。 这个时候可以用动态引入的方式加载JSON文件,比如用户点击节日主题Banner的时候再加载对应的JSON文件,或者用Vue的路由懒加载,在进入对应页面的时候再加载。

    预加载关键动效

    虽然按需加载很重要,但一些关键动效,比如首页的加载动效,或者支付成功后的动效,最好还是预加载一下,不然用户等半天动效才出来,体验不好。 预加载的方式也很简单,可以用LottieFiles的LottiePlayer组件的preload参数,或者用lottie-web的loadAnimation方法先把JSON文件加载到内存里,等需要用的时候直接渲染。

    精简JSON文件

    这是最根本的性能优化方式,不管前端怎么优化,都不如设计师精简JSON文件来得直接,可以让设计师在导出JSON的时候注意以下几点:

  • 合并重复的图层;
  • 去掉非关键的关键帧,尤其是那些变化很小的关键帧;
  • 尽量用AE里Lottie支持的插件和效果,不要用第三方不支持的插件;
  • 如果动效里有图片,尽量把图片转换成矢量图层,或者把图片压缩后内嵌到JSON文件里,或者把图片放到CDN上,通过绝对路径引用。

    控制同时渲染的动效数量

    如果页面里同时有多个Lottie动效,比如产品列表里每个产品都有一个小动效,这个时候尽量不要让所有动效同时自动播放,可以让用户滚动到视口的时候再播放,或者只让前几个动效自动播放,后面的等用户交互的时候再播放。 怎么判断动效是否在视口呢?可以用Intersection Observer API,这个API比用scroll事件监听性能好很多,而且Vue3也有对应的插件,比如vue-intersect,或者自己写一个简单的Composition API的hook。

两个主流Vue3 Lottie库怎么选?

刚才主要讲了vue3-lottie,还有一个是lottie-web的Vue3封装,也就是lottie-vue3,这两个库有什么区别呢?

vue3-lottie

  • 优点:官方社区维护,更新比较频繁,对Composition API和Options API都友好,TypeScript支持全,封装了很多常用的参数和事件,比如autoplay、loop、tintColor、colorFilters、complete事件、click事件,新手很容易上手;
  • 缺点:功能相对少一点,很多高级功能还是要用到lottie-web的原生API。

    lottie-vue3(或者直接用lottie-web自己封装)

  • 优点:是Airbnb Lottie官方提供的,功能最全,所有lottie-web的API都能用,适合做复杂的自定义动效;
  • 缺点:封装得比较简单,很多常用的参数和事件都要自己写,新手可能会有点难上手。 新手和做简单动效的项目,推荐用vue3-lottie;做复杂自定义动效的项目,推荐用lottie-vue3或者直接用lottie-web自己封装一个组件。

总结一下

Vue3搭配Lottie,真的是前端动效的黄金组合,能快速、稳定地实现1:1还原的高质量动效,而且JSON文件体积小,性能好。 新手先上手vue3-lottie,按照基础流程来,遇到空白、颜色不对、卡顿这些常见问题,按照刚才讲的坑点排查就行;要用到生产环境里,记得选对渲染器、按需加载、预加载关键动效、精简JSON文件、控制同时渲染的动效数量。 如果有复杂的自定义需求,再换成lottie-vue3或者直接用lottie-web自己封装。 别忘了拿到设计师的JSON文件先“验验货”,不然前端写半天代码都是白搭。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门