记录解决动画在IOS上卡顿的问题


IOS动画卡顿问题

问题描述

使用css+js实现不断生成元素并向后滑动,越往后滑动元素越小的效果,但是在IOS上滑动看起来一顿一顿的。
大致代码如下(vue2):

// 父组件
<Obj
   v-for="obj in objs"
   :key="obj.id"
   :obj="obj"
 />
 // methods
createAnimation() {
  const update = t => {
    // ...
    // 每1s增加一个元素
    if (...) {
      this.addObj();
    }
    // 每1帧,通过js修改元素位置和尺寸
    this.objs.forEach((obj, index) => {
      obj.offsetY += ...;
      obj.scale += ...;
      obj.offsetX += ...;
    });
    requestAnimationFrame(update);
  };
  requestAnimationFrame(update);
}
 
 
 // Obj组件
 <img class="obj" ref="obj":src="img" :style="getStyle" />
// computed
getStyle() {
  // 通过computed计算元素大小和位置
  return {
    width: this.obj.width,
    marginLeft: -this.obj.width / 2,
    transform: `translate(${this.obj.offsetX}, ${
      this.obj.offsetY
    }) scale(${this.obj.scale})`
  };
}

解决:

使用元素.animate()创建动画

// 父组件
createAnimation() {
  const update = t => {
    // ...

    // 不在这里修改元素位置和尺寸
    // this.objs.forEach((obj, index) => {
    //   obj.offsetY += ...;
    //   obj.scale += ...;
    //   obj.offsetX += ...;
    // });
    requestAnimationFrame(update);
  };
  requestAnimationFrame(update);
}

// Obj组件 mounted里调用
async createObjAnimation() {
  let obj = this.$refs.obj;
  const keyframe = [
  	// 初始位置和尺寸
    {
      transform: `translate(${this.obj.offsetX}, ${
        this.obj.offsetY
      }) scale(1)`
    },
    // 3s后,该元素动画结束时的位置和尺寸
    {
      transform: `translate(${this.obj.finalOffsetX}, ${
        this.obj.finalOffsetY
      }) scale(0.3)`
    }
  ];
  this.animation = obj.animate(keyframe, {
    duration: 3000,
    easing: "linear"
  });
  this.animation.play();
}

失败尝试

  1. 使用will-change: transform; 发现没有效果。
  2. 观察卡顿情况,发现好像是每次生成一个新的元素,页面上已存在的滑动元素就会顿一下,所以尝试一开始生成所有需要的元素,然后再js+css每隔1s依次移动1个元素,发现还是卡。

补充

版本较低的iOS可能不支持这种方式(我的iOS版本为12.1.4,可以显示卡顿的那种效果,但是换成animate()页面上无法显示元素)。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值