前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React: Lottie 动画初体验和优化策略

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

作者头像
西南_张家辉
发布2021-02-02 10:23:12
3.6K0
发布2021-02-02 10:23:12
举报
文章被收录于专栏:张家辉的树屋张家辉的树屋

阅读大约需要 12-15 分钟, 主要简单介绍 lottie 动画概况和一些优化方案, 主要的优化方案针对React h5 的优化方案

1、什么是 LOTTIE

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

srS2vt.gif
srS2vt.gif

简单来讲就是 UI 设计师用 AE 解析出 JSON 动画,前端工程师使用 JSON 文件在 lottie-web 等框架下进行 svg (canvas/html) 渲染

2、看几个简单的 DEMO

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

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

4、简单的原理解析

来看看 bodymovin 动画的渲染基本流程

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

5、React 项目实现

  • 设计同学设计动画, AE 导出 zip 动画包,这里我们先使用 lottiefiles一下,然后可以根据情况来使用动画资源,一般是直接使用 json 文件即可;具体 React 项目如下,安装 `react-lottie
代码语言:javascript
复制
npm install react-lottie
  • 导入 json 文件
代码语言:javascript
复制
import Lottie from "lottie-react";
import groovyWalkAnimation from "./groovyWalk.json";

const Example = () => {
  return <Lottie animationData={groovyWalkAnimation} />;
};

export default Example;
复制代码

实现比较简单

6、优化策略

  • 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 相关的可以获取更多手机信息做个别低端手机黑名单,完全禁止动画

7、实践

  • 1、2 可以在大部分场景实现,这里只讨论上诉 3,4,5 的可行性

7.3、虚拟 dom

7.4、使用 inview

  • 可视范围的监控这里主要使用了 Intersection Observer API
    • 其中这个 api 最主要使用了 Intersection Observer API 会注册一个回调函数,每当被监视的元素进入或者退出另外一个元素时(或者 viewport ),或者两个元素的相交部分大小发生变化时,该回调方法会被触发执行。这样,我们网站的主线程不需要再为了监听元素相交而辛苦劳作,浏览器会自行优化元素相交管理。
    • 解决了资源懒加载——当图片滚动到可见时才进行加载
代码语言:javascript
复制
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>
}
复制代码

7.5、几种测算 web FPS 的方法

  • 7.5.1 requestAnimateFrame

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

代码语言:javascript
复制
window.requestAnimationFrame(callback);
  • requestAnimateFrame 想必前端同学在做一些 js 动画的时候已经比较了解了;告诉浏览器您希望执行动画并请求浏览器调用指定的函数在下一次重绘之前更新动画;
  • 具体的实现如下,测算浏览器页面渲染的动画 FPS
代码语言:javascript
复制
// 处理兼容性问题
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();
复制代码

下面看看掘金主页的加载速度

syePbQ.png
syePbQ.png
  • 值得注意的是,这个方法计算的结果和真实的帧率肯定是存在误差的,因为它是将每两次主线程执行 javascript 的时间间隔当成一帧,而非上面说的主线程加合成线程所消耗的时间为一帧。但是对于现阶段而言,算是一种可取的方法。
  • 7.5.2 chrome 开发者工具
    • 控制台-> perfmance -> 刷新页面开启监控性能,然后就能看到 frames 这项性能指标(右上角有 fps 的帧率控制)
syngHg.jpg
syngHg.jpg
  • 7.5.3 Frame API
    • 什么是 Frame Timing API ?

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

代码语言:javascript
复制
- Web Performance Timing API 是 W3C 推出的一套性能 API 标准,用于帮助开发者对网站各方面的性能进行精确的分析与控制,提升 Web 网站性能。
代码语言:javascript
复制
var rendererEvents = window.performance.getEntriesByType("renderer");

// 下面可以看到 render 的时间
{
  sourceFrameNumber: 120,
  startTime: 1342.549374253
  cpuTime: 6.454313323
}
syV0yD.png
syV0yD.png

但是这个 api 还在试验阶段,各大浏览器都不支持所以只是暂时讨论和了解一下就可以了,不能正式的开发使用;

参考

邀请

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、什么是 LOTTIE
  • 2、看几个简单的 DEMO
  • 3、为什么选择 LOTTIE 动画,比较同样类型和选择
  • 4、简单的原理解析
  • 5、React 项目实现
  • 6、优化策略
  • 7、实践
    • 7.3、虚拟 dom
      • 7.4、使用 inview
        • 7.5、几种测算 web FPS 的方法
        • 参考
        • 邀请
        相关产品与服务
        云开发 CLI 工具
        云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档