最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React Lottie 动画初体验和优化策略

    正文概述 掘金(西南_张家辉)   2021-01-18   994

    1、什么是 LOTTIE

    lottie 是 Aribnb 开源一个主要面向 Web、iOS、Android、React Native、Windows 的动画库,可以实时渲染After Effects动画,并以Bodymovin作为json导出,允许应用程序像使用静态图像一样轻松使用动画,一款协同合作的高效软件。

    React Lottie 动画初体验和优化策略

    2、看几个简单的 DEMO

    • 先看几个web 端直接使用 bodymovin 库渲染的 demo
      • codepen demo1 watching
      • codepen demo2 error!

    3、为什么选择 LOTTIE 动画,比较同样类型和选择

    • 同样类型的复杂动画实现的方案现在有如下几个

        1. png 序列帧:
        • 优点:兼容性好,工程师可控,操作性强
        • 缺点:它需要大量图片素材支持,动画播放时占用的内存较多
        1. 视频:
        • 优点:兼容性好,适配工作少
        • 缺点:交互弱,加载成本高
        1. gif:
        • 优点:实现简单。
        • 缺点:部分手机掉帧非常严重,体验不流畅,严重影响用户体验
    • lottie 动画就解决了这一问题:Lottie 只需要解析导出的 JSON 文件及所需要的图片,就能在各个平台上实现相同的动画效果,它实现成本低,上线后只需要动态替换对应的 JSON 文件就能实现可配置、可运营

    3、简单的原理解析

    • 1、 registerAnimation
      • 注册动画,创建一个AnimationItem的容器,把我们的节点elementanimationData json数据进行初始化
    • 2、 setData,setParams
      • animationData 设置基础值, 来确定数据来源并初始化数据,解析 svg/canvas/html 渲染方式
    • 3、 configAnimation
      • 挂载动画数据的参数
    • 4、 loadAnimation
      • load 动画
    function loadAnimation(params){
        var animItem = new AnimationItem();
        setupAnimation(animItem, null);
        animItem.setParams(params);
        return animItem;
    }
    
    • 其实lottie是用了 requestAnimationFrame----在于充分利用显示器的刷新机制,比较节省系统资源。

    4、React 项目实现

    • 设计同学设计动画, AE 导出 zip 动画包,这里我们先使用 lottiefiles一下,然后可以根据情况来使用动画资源,一般是直接使用 json 文件即可;具体 React 项目如下,安装 `react-lottie
    npm install react-lottie
    
    • 导入 json 文件
    import Lottie from "lottie-react";
    import groovyWalkAnimation from "./groovyWalk.json";
    
    const Example = () => {
      return <Lottie animationData={groovyWalkAnimation} />;
    };
    
    export default Example;
    

    5、优化策略

    • 1、监控用户滑动事件,按页加载当前动画
    • 2、设计师侧优化(减少动画帧数,和动画数量)
    • 3、虚拟 DOM (react virtual dom)[https://swiperjs.com/api/#virtual] 减少页面的渲染压力;
    • 4、可视范围监控 (可视范围 开启动画 inview 显示)[https://github.com/bitmap/react-hook-inview]
    • 5、根据手机性能,优雅降级
      • (requestAnimationFrame)[http://zhangchen915.com/index.php/archives/675/]
      • window.performance
      • Frame API
      • react native 相关的可以获取更多手机信息做个别低端手机黑名单,完全禁止动画

    6、实践

    • 1、2 可以在大部分场景实现,这里只讨论上诉 3,4,5 的可行性
    6.3、虚拟 dom
    • 借助了 react 虚拟 dom 的特性,在 swiper 上实现了;具体的原理可以看这篇文章alloyteam 浅析virtual dom
    6.4、使用 inview
    • 可视范围的监控这里主要使用了 Intersection Observer API
      • 其中这个 api 最主要使用了 Intersection Observer API 会注册一个回调函数,每当被监视的元素进入或者退出另外一个元素时(或者 viewport ),或者两个元素的相交部分大小发生变化时,该回调方法会被触发执行。这样,我们网站的主线程不需要再为了监听元素相交而辛苦劳作,浏览器会自行优化元素相交管理。
      • 解决了资源懒加载——当图片滚动到可见时才进行加载
    import { useInView } from 'react-intersection-observer';
    import Lottie from 'react-lottie';
    import LOTTIE_ANIM_JSON from './lottie.json';
    
    const Anim = ()=>{
      const { ref: $LOTTIE_ANIM_JSON_REF; View: $LOTTIE_ANIM_JSON_VIEW } = useInView();
      const $ANIM = (
        <Lottie
        options={{
          loop: true,
          autoplay: true,
          animationData: LOTTIE_ANIM_JSON,
        }}
        isPaused={!LOTTIE_ANIM_JSON_VIEW}
        />
        );
    
      return  <div className="lottie" ref={$LOTTIE_ANIM_JSON_REF}>
        {$ANIM}
      </div>
    }
    
    6.5、几种测算 web FPS 的方法
    • 6.5.1 requestAnimateFrame

    基于 lottie 动画的原理特性充分的利用 requestAnimationframe 特性

    window.requestAnimationFrame(callback);
    
    • requestAnimateFrame 想必前端同学在做一些 js 动画的时候已经比较了解了;告诉浏览器您希望执行动画并请求浏览器调用指定的函数在下一次重绘之前更新动画;

    • 具体的实现如下,测算浏览器页面渲染的动画 FPS

    // 处理兼容性问题
    var rAF = function () {
        return (
            window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            function (callback) {
                window.setTimeout(callback, 1000 / 60);
            }
        );
    }();
     
    var frame = 0;
    var allFrameCount = 0;
    var lastTime = Date.now();
    var lastFameTime = Date.now();
     
    var loop = function () {
        var now = Date.now();
        var fs = (now - lastFameTime);
        var fps = Math.round(1000 / fs);
     
        lastFameTime = now;
        // 不置 0,在动画的开头及结尾记录此值的差值算出 FPS
        allFrameCount++;
        frame++;
     
        if (now > 1000 + lastTime) {
            var fps = Math.round((frame * 1000) / (now - lastTime));
            console.log(`${new Date()} 1S内 FPS:`, fps); 
            frame = 0;
            lastTime = now;
        };
     
        rAF(loop);
    }
    
    loop();
    

    React Lottie 动画初体验和优化策略

    • 值得注意的是,这个方法计算的结果和真实的帧率肯定是存在误差的,因为它是将每两次主线程执行 javascript 的时间间隔当成一帧,而非上面说的主线程加合成线程所消耗的时间为一帧。但是对于现阶段而言,算是一种可取的方法。

    • 6.5.2 chrome 开发者工具

      • 控制台-> perfmance -> 刷新页面开启监控性能,然后就能看到 frames 这项性能指标(右上角有 fps 的帧率控制)

    React Lottie 动画初体验和优化策略

    • 6.5.3 Frame API
      • 什么是 Frame Timing API ?

    Frame Timing API 是 Web Performance Timing API 标准中的其中一位成员。

    - Web Performance Timing API 是 W3C 推出的一套性能 API 标准,用于帮助开发者对网站各方面的性能进行精确的分析与控制,提升 Web 网站性能。
    
    var rendererEvents = window.performance.getEntriesByType("renderer");
    
    // 下面可以看到 render 的时间
    {
      sourceFrameNumber: 120,
      startTime: 1342.549374253
      cpuTime: 6.454313323
    }
    

    React Lottie 动画初体验和优化策略

    参考

    • [1] Awesome List
    • [2] bodymovin
    • [3] lottie 动画原理
    • [4] lottie 动画
    • [5] 生成原理/性能分析
    • [6] 虚拟 dom 原理
    • [7] 计算 web 页面性能

    起源地下载网 » React Lottie 动画初体验和优化策略

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元