出现场景:

在做一个小球跟随手指移动的效果时候,由于在touchmove事件中频繁调用setData改变小球的位移实现,在开发工具和IOS平台还算流畅,但在安卓机下手机预览出现极其卡顿的交互,简直是不堪入目。

可微信web开发者工具打开 片段代码https://developers.weixin.qq.com/s/B9UHyvmo7t6t

问题根源:

setData每秒调用高达50左右造成的。 引用官方的话就是:

a、touchmove 事件从视图层(Webview)抛到逻辑层(App Service)

b、逻辑层(App Service)处理 touchmove 事件,再通过 setData 来改变 组件 的位置

一次 touchmove 的响应需要经过 2 次的逻辑层和渲染层的通信以及一次渲染,通信的耗时比较大。此外 setData 渲染也会阻塞其它脚本执行,导致了整个用户交互的动画过程会有延迟。

如何优化?

1.使用movable-view

movable-view + movable-area可实现移动效果很流畅,但是也有局限性不能满足复杂的需求,例如现在需求需要是两个小球使用两个手指能同时控制小球移动,则无法实现,还需要配合setData来实现,使用了setData必然会出现卡顿

2.推荐方案:抛弃setData,使用wxs来写交互

从基础库 2.4.4 开始支持 WXS响应事件 直接上代码,本人菜鸟,代码写的很乱:

index.js

const app = getApp()Page({data: {balls: [1, 2, 3, 4, 5, 5, 6, 7]}
})

index.wxml

//引入wxs文件
<wxs module="index" src="./index.wxs"></wxs>
<view class='wrap' catchtouchstart='{{index.touchstart}}' catchtouchmove='{{index.touchmove}}' catchtouchend='{{index.touchend}}'><view class="demo hide" wx:for="{{ balls }}"></view>
</view>

index.wxs

var allTouchs = [], len = 0, instances = [], instanceLen, isMoveEnd = falsefunction reset(ownerInstance) {//重置for (var i = 0; i < instanceLen; i++) {instances[i].setStyle({'transform': '','display': 'none'})}
}function touchstart(event, ownerInstance) {if (isMoveEnd) return//获取当前移动的手指var bounds = event.touches, boundsLen = bounds.lengthallTouchs = event.touches, len = event.touches.lengthinstances = ownerInstance.selectAllComponents('.demo'), instanceLen = instances.lengthfor (var i = 0; i < instanceLen; i++) {var instance = instances[i], bound = bounds[i]if (i < boundsLen) {//更新instance.disabled = falseinstance.identifier = bound.identifierinstance.setStyle({'transform': 'translateX(' + bound.pageX + 'px) translateY(' + bound.pageY + 'px)','display': 'block'})} else {instance.setStyle({'transform': '','display': 'none'})instance.disabled = trueinstance.identifier = ''}}
}function touchmove(event, ownerInstance) {//获取当前移动的手指var bounds = event.changedTouches, boundsLen = bounds.length, bound = null, instance = null, allTouch = nullfor (var i = 0; i < instanceLen; i++) {instance = instances[i]for (var j = 0; j < boundsLen; j++) {bound = bounds[j]if (instance.identifier === bound.identifier) {//更新instance.setStyle({'transform': 'translateX(' + bound.pageX + 'px) translateY(' + bound.pageY + 'px)','display': 'block'})}}}
}function touchend(event, ownerInstance) {isMoveEnd = true//获取当前移动的手指var bounds = event.changedTouches, boundsLen = bounds.length, bound = null, instance = null, allTouch = nullfor (var i = 0; i < instanceLen; i++) {instance = instances[i]for (var j = 0; j < boundsLen; j++) {bound = bounds[j]if (instance.identifier === bound.identifier) {//更新instance.setStyle({'transform': '','display': 'none'})//移除instances[i].disabled = trueinstances[i].identifier = ''}}}var tmp = instances.filter(function (item) {return !item.disabled})if (tmp.length < 1) {//重置reset(ownerInstance)}isMoveEnd = false
}
module.exports = {touchmove: touchmove,touchend: touchend,touchstart: touchstart
}

微信web开发者工具打开小程序代码片段https://developers.weixin.qq.com/s/wLxQuwm1786m

instance对象支持的方法:

常用的就是获取组件(类似于获取dom节点),和设置样式和class,调用app service方法 除了以上方法,还有强大的触发器函数的使用,可监听appservice 层中的data变化,具体demo请查看官方文档 官方文档

经过实机测试,不出出现卡顿效果

注意事项

官方bug:

个人总结bug:
1.wxs不能使用ES6+语法,否则会报错(勾选了ES6转ES5也没用)

2.console.log()不能直接打印对象,需要JSON.stringify

3.当然不能调用app service环境中的方法和wx.xxxx方法

作者:jionchen
链接:https://juejin.im/post/5c7749aee51d451ecc20215c

转载于:https://blog.csdn.net/rolan1993/article/details/88106343

小程序touchmove事件中setData优化过程相关推荐

  1. 微信小程序 使用vant-weapp中的索引栏右侧点不动,滚定索引失效问题

    微信小程序 使用vant-weapp中的索引栏右侧点不动,滚定索引失效问题 vant的索引栏只要使用了定位,或者自定义头部,那么vant的索引栏就会出现各种BUG,基本不能用,这里我是基本重新写了一个 ...

  2. 快手小程序常用事件绑定使用场景总结

    快手小程序常用事件使用场景说明与总结 bindtap="clickMe" 点击事件 // 实现返回上一页动作 clickMe:function(){ks.navigateBack( ...

  3. 初级前端小程序项目加载速度优化

    这份文字是根据近期团队做来问丁香医生 SPA 和 丁香医生小程序 加载速度优化的经历整理而成. 效果 古人有一句话叫做:治感冒看疗效.既然是关于速度优化的,我们就先来看一下优化的效果. 来问丁香医生 ...

  4. 微信小程序学习4:小程序语法 - 事件绑定

    微信小程序学习4:小程序语法 - 事件绑定 事件绑定最简单的例子是,你设置一个按钮为可触发的,触发条件可以是点击,按压,长按等等.当然,如果你仅仅是设置了触发事件,而没有创建回调函数,是不会产生什么效 ...

  5. wxml修改样式_微信小程序 动态绑定事件并实现事件修改样式

    微信小程序 动态绑定事件并实现事件修改样式 实例代码 wxml {{item.name}} js var reportTypeList = [ { name: "日报1", id: ...

  6. 微信小程序阻止冒泡点击_微信小程序bindtap事件与冒泡阻止详解

    bindtap就是点击事件 在.wxml文件绑定: cilck here 在一个组件的属性上添加bindtap并赋予一个值(一个函数名) 当点击该组件时, 会触发相应的函数执行 在后台.js文件中定义 ...

  7. 「小程序JAVA实战」 小程序的事件(11)

    转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-11/ 我们以前在web开发的时候,web页面也有一些相关的事件,当然小程序要接触屏幕要进行一些点击 ...

  8. 小程序授权登录的体验优化

    小程序授权登录的体验优化 大多数小程序的登录,都是这样设计的: 进来就提示你需要授权,有部分人可能就会点"拒绝"(拒绝的比例可能超出我们的预估) 然后在后续操作的时候,就进行不下去 ...

  9. 微信小程序 - 绑定事件 bindtap(包括是否传入参数)

      小程序绑定事件的方式有很多种,这里我只对bindtap的绑定方式进行介绍,其他的绑定方式也是差不多这样的. 1.不带参数的绑定方式 index.wxml文件中:share表示绑定的事件名称 < ...

最新文章

  1. Serverless 在大厂都怎么用?
  2. 【Groovy】编译时元编程 ( 编译时元编程引入 | 声明需要编译时处理的类 | 分析 Groovy 类的 AST 语法树 )
  3. Windows Mobile设备操作演示准备工作小记
  4. 数据仓库建设从0到1-一文带你深入建设金融数仓体系
  5. android按钮点击后闪退_Android开发【04-27求助贴】点击button闪退
  6. NVIDIA英伟达的Multi-GPU多卡通信框架NCCL
  7. js如何判断访问来源是来自搜索引擎(蜘蛛人)还是直接访问
  8. list遍历_Python遍历list,使用range和enumerate的效率区别
  9. 思科:企业数据中心技术产品采购放缓
  10. 肯辛通VeriMark指纹识别器 驱动下载 与 安装指南(含视频教程) 型号:K67977 K64704 K62330
  11. 教程:如何使用Java以编程方式打印PDF文件?
  12. Git出现 Your local changes to the following files would be overwritten by merge: con
  13. 【递归入门】走迷宫(c++)
  14. 各种说明方法的例句_11个说明方法句子
  15. Launching unittests with arguments python -m unittest
  16. python编写函数showmsg(n、name)_python学习-函数
  17. 计算机因特尔网络论文,电子商务课Intel未来教育理念论文
  18. ROS中执行roslaunch后,显示功能包不存在的解决方法
  19. Andriod 电池检测NTC电阻值的软件设定
  20. JS键盘事件—onkeydown,onkeyup

热门文章

  1. Python 开发这些牛逼的 App
  2. 深入浅出matplotlib(35):设置坐标轴个性化显示标签
  3. The import java.io cannot be resolved (类库无法解析的问题解决 )
  4. 最字头之一:最长公共子序列
  5. 请提前布局 Star Trek突破链游全新玩法,市场热度持续高涨
  6. 刺客信条-【设计模式】-软件设计准则
  7. java中printf和println的区别
  8. Java常用类库之Arrays
  9. 从键盘输入姓名及5门课成绩
  10. 人生不一定有那么多重逢