小程序touchmove事件中setData优化过程

2023-10-13 01:08

本文主要是介绍小程序touchmove事件中setData优化过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

出现场景:

在做一个小球跟随手指移动的效果时候,由于在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

 

这篇关于小程序touchmove事件中setData优化过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/199694

相关文章

将Java程序打包成EXE文件的实现方式

《将Java程序打包成EXE文件的实现方式》:本文主要介绍将Java程序打包成EXE文件的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录如何将Java程序编程打包成EXE文件1.准备Java程序2.生成JAR包3.选择并安装打包工具4.配置Launch4

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

PyInstaller打包selenium-wire过程中常见问题和解决指南

《PyInstaller打包selenium-wire过程中常见问题和解决指南》常用的打包工具PyInstaller能将Python项目打包成单个可执行文件,但也会因为兼容性问题和路径管理而出现各种运... 目录前言1. 背景2. 可能遇到的问题概述3. PyInstaller 打包步骤及参数配置4. 依赖

SpringBoot实现微信小程序支付功能

《SpringBoot实现微信小程序支付功能》小程序支付功能已成为众多应用的核心需求之一,本文主要介绍了SpringBoot实现微信小程序支付功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录一、引言二、准备工作(一)微信支付商户平台配置(二)Spring Boot项目搭建(三)配置文件

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

将Mybatis升级为Mybatis-Plus的详细过程

《将Mybatis升级为Mybatis-Plus的详细过程》本文详细介绍了在若依管理系统(v3.8.8)中将MyBatis升级为MyBatis-Plus的过程,旨在提升开发效率,通过本文,开发者可实现... 目录说明流程增加依赖修改配置文件注释掉MyBATisConfig里面的Bean代码生成使用IDEA生

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,