记录lottie动画踩坑(内存泄漏、帧误差、销毁方式)

发布网友 发布时间:2024-10-02 18:22

我来回答

1个回答

热心网友 时间:2024-10-18 07:51

1.内存泄露

我测试的是AE文件导出的lottie文件(单个动画对象包含3个蒙版,3-5个元素,无渐变颜色,动画时长1s。一共有3-4个这样的动画对象),这样的动画如果不对lottie生成的对象进行销毁的话,经过测试存在内存泄露问题,不使用缓存机制,会导致长时间使用下,内存占用持续走高:

这里使用单实例模式,缓存anim对象的引用,可以平衡内存的使用。

??//?Singleton??if?(anim)?{????anim.doSth();??}?else?{????anim?=?lottie.loadAnimation(data);??}

结果如图,没有内存占用持续走高的现象发生:

2.帧误差?

在调用,anim.play()方法后,动画会从第0帧执行到最后一帧停止,正常情况下是不会出问题的。

但是在暴力测试下,如果频繁触发动画执行,会导致终点动画的结束帧有误差,比如我做的60帧的动画,在暴力测试下,会导致终点帧为59帧,如图:

这样的话,下次再执行anim.play方法时,是从第59帧执行到60帧,而不是从第0帧执行到第60帧(即replay),所以这里需要定义一个方法使其replay。?

??const?replay?=?(anim:?AnimationItem)?=>?{????if?(anim.currentFrame?!==?anim.totalFrames)?anim.goToAndStop(anim.totalFrames,?true);????anim.play();??};

3.销毁方式

这里在销毁的地方,effecthook上踩了一个坑,location会因为路由变化,重新触发effecthook。

这里需要注意,如果一个effect同时包含return函数和refs的时候,如果refs变化,那么这时return函数会执行,以清除上一次effect。

所以因为location的变化,在当前这个effecthook里,我把anim给销毁了,那么就会存在一些判断逻辑上的缺漏!!

所以最好的hook使用方式,应该是将会有相互影响的hook分开来写,创建/销毁应该清晰化去处理,这样才不会产生连串效应。

const?location?=?useLocation();?//?react?router?dom//?wrong?wayuseEffect(()?=>?{??//?add?event?listener?on?location's?change?events??//?...?deal?events??return?()?=>?{????anim?&&?anim.destroy()??}},?[location])//?correct?wayuseEffect(()?=>?{??//?add?event?listener?on?location's?change?events??//?...?deal?events},?[location])useEffect(()?=>?{??return?()?=>?{????anim?&&?anim.destroy()??}},?[])

4.结束语

如果觉得写的不错,有用的话,还请帮我点个赞O(∩_∩)O

转发请注明出处,谢谢!

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com