找回密码
 会员注册
查看: 20|回复: 0

飞书中Lottie动画的应用

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
72910
发表于 2024-10-2 17:45:13 | 显示全部楼层 |阅读模式
背景飞书项目中 loading 常用的动画方案是 Gif 动画。Gif 动画存在一定的问题,Gif 文件一般较大,且呈现的大小是固定的,无法缩放以匹配大屏幕和高密度屏幕,容易有锯齿,不能控制动画。其他常用的动画方案:Png 序列帧:合成的雪碧图文件大,且在不同屏幕分辨率下可能会失真SVG 动画:实现成本高,容易出现动画还原度低的情况目前项目中需要一种更加简单、高效、性能好、还原度高的动画方案,设计同学正在推动 AE + bodymovin 导出动画配置的方案,经过调研发现 Lottie 动画是一种可行性较高的方案。Lottie 简介Lottie[1]是 airbnb 开源的可应用于Android[2],iOS[3],Web[4],React Native[5]和Windows[6]动画库, 本质上是一套跨平台的动画解决方案。它提供了一套完整的从 AE 到各个终端的工具流,通过 AE 的 Bodymovin 插件将设计师做的动画导出成一套定义好的 json 文件,之后再通过 Lottie 各端的库就可以实现动画效果,动画还原度 100%,Lottie-web Example[7]。使用方法lottie-web[8]支持特性最多(http://airbnb.io/lottie/#/supported-features),可以实现较为复杂的动画,控制动画的播放,监听动画各个阶段的事件(https://github.com/airbnb/lottie-web)。lottie-web[9]的使用方法, 有三种渲染方式 svg, canvas, html, 一般常用 svg, canvaslottie.loadAnimation({container:element,//thedomelementthatwillcontaintheanimationrenderer:'svg',loop:true,autoplay:true,path:'data.json'//thepathtotheanimationjson});react-lottie[10]的使用方法(将lottie-web[11]封装成 React 组件)importReactfrom'react'importLottiefrom'react-lottie';import*asanimationDatafrom'./pinjump.json'exportdefaultclassLottieControlextendsReact.Component{constructor(props){super(props);this.state={isStopped:false,isPaused:false};}render(){constbuttonStyle={display:'block',margin:'10pxauto'};constdefaultOptions={loop:true,autoplay:true,animationData:animationData,rendererSettings:{preserveAspectRatio:'xMidYMidslice'}};returnthis.setState({isStopped:true})}>stopthis.setState({isStopped:false})}>playthis.setState({isPaused:!this.state.isPaused})}>pause}}控制动画播放的方法:名称描述animation.play播放该动画,从目前停止的帧开始播放stop停止播放该动画,回到第 0 帧pause暂停该动画,在当前帧停止并保持goToAndStopanimation.goToAndStop(value, isFrame);跳到某个时刻/帧并停止。isFrame(默认 false)指示 value 表示帧还是时间(毫秒)goToAndPlayanimation.goToAndPlay(value, isFrame);跳到某个时刻/帧并进行播放goToAndStopanimation.goToAndStop(30, true);跳转到第 30 帧并停止playSegmentsanimation.playSegments(arr, forceFlag);arr 可以包含两个数字或者两个数字组成的数组,forceFlag 表示是否立即强制播放该片段 animation.playSegments([10,20], false);播放完之前的片段,播放 10-20 帧 animation.playSegments([[0,5],[10,18]], true);直接播放 0-5 帧和 10-18 帧setSpeedanimation.setSpeed(speed);设置播放速度,speed 为 1 表示正常速度setDirectionanimation.setDirection(direction);设置播放方向,1 表示正向播放,-1 表示反向播放destroyanimation.destroy();删除该动画,移除相应的元素标签等。在 unmount 的时候,需要调用该方法监听事件:名称描述data_ready加载完 json 动画complete播放完成(循环播放下不会触发)loopComplete当前循环下播放(循环播放/非循环播放)结束时触发enterFrame每进入一帧就会触发,播放时每一帧都会触发一次,stop 方法也会触发segmentStart每进入一帧就会触发,播放时每一帧都会触发一次,stop 方法也会触发DOMLoaded动画相关的 dom 已经被添加到 html 后触发destroy将在动画删除时触发Lottie 动画性能测试Lottie 局部加载动画, Gif 动画 与 Lottie 动画比较Gif 动画性能1,加载编译库文件的耗时(阻塞启动)平均:25ms2,lottie-web 文件本身的内存占用shadow size: 136B Retained Size: 1209553B3,执行时的耗时(体现到耗时上,CPU 采样会很不精准,阻塞业务逻辑,如启动 chat)平均:15.4msLottie 动画性能由上图可知,查看了 Gif 动画、Lottie 动画方案的 FPS、CPU 占用率、GPU 占用、Scripting、Rendering、Painting、内存的使用情况。方案大小FPSCPU 占用率GPU 占用内存Gif 动画279KB8-60fps, 多数帧率 50fps, 帧率波动较多0%28.6MB94527Lottie 动画4KB (json 文件)242.2KB( lottie-web js 文件)20-60fps, 多数帧率 59fps,帧率较稳定,波动少0%21.1MB94825通过以上数据分析,可知 Lottie 动画的配置文件较小,帧率较高,GPU 占用低,内存与 Gif 动画相差不大,性能较好。Lottie 动画方案简单、高效、性能好,可以替代传统的 GIF 和帧动画,灵活利用好提供的属性和方法可以控制动画的播放。注意事项及时卸载 Lottie 动画组件在不需要 Lottie 动画时,需要及时卸载 Lottie 动画组件飞书出现过偶现 CPU 升高的异常案例,经过排查定位到是 Lottie 动画没有卸载引起的 CPU 升高。页面中已经没有动画,但 Lottie 一直在调用 requestAnimationFrame,导致在没有任何操作的情况下,CPU 占用升高至 2%-5% 左右,一般情况在没有任何操作的情况下,cpu 占用 0.1% ~0.2%。Lottie 动画调用 react-lottie 组件,组件在 componentWillUnmount 时,会销毁该动画实例。飞书中 CPU 升高的时候,发现 Lottie 动画中有动画实例尚未销毁,导致会不停的调用 requestAnimationFrame,导致异常的动画是局部加载动画。飞书中用到局部加载的动画的模块有主端(切换会话、联系人页面 、新添加的联系人、机器人、外部联系人、onCall、升级提示弹窗、添加联系搜索、发送云盘文件弹窗、Pin 列表、Docs Webview 加载动画、切换租户)、日历、应用中心等。经过定位发现,应用中心里用到了局部加载动画, 在不需要动画的时候,没有卸载组件,只是通过 CSS 来隐藏了组件,导致没有销毁 Lottie 动画实例,requestAnimationFrame 会一直执行,代码如下://AppHome.js 不需要 Lottie 动画的时候,卸载 Lottie 动画组件。//AppHome.js{!!isLoading&( )}参考资料[1]Lottie:http://airbnb.io/lottie/#/[2]Android:https://github.com/airbnb/lottie-android[3]iOS:https://github.com/airbnb/lottie-ios[4]Web:https://github.com/airbnb/lottie-web[5]React Native:https://github.com/airbnb/lottie-react-native[6]Windows:https://aka.ms/lottie[7]Lottie-web Example:https://codepen.io/collection/nVYWZR/[8]lottie-web:https://github.com/airbnb/lottie-web[9]lottie-web:https://github.com/airbnb/lottie-web[10]react-lottie:https://github.com/chenqingspring/react-lottie[11]lottie-web:https://github.com/airbnb/lottie-web
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-12 09:01 , Processed in 0.926689 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表