小程序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

相关文章

springboot3.x使用@NacosValue无法获取配置信息的解决过程

《springboot3.x使用@NacosValue无法获取配置信息的解决过程》在SpringBoot3.x中升级Nacos依赖后,使用@NacosValue无法动态获取配置,通过引入SpringC... 目录一、python问题描述二、解决方案总结一、问题描述springboot从2android.x

MySQL数据目录迁移的完整过程

《MySQL数据目录迁移的完整过程》文章详细介绍了将MySQL数据目录迁移到新硬盘的整个过程,包括新硬盘挂载、创建新的数据目录、迁移数据(推荐使用两遍rsync方案)、修改MySQL配置文件和重启验证... 目录1,新硬盘挂载(如果有的话)2,创建新的 mysql 数据目录3,迁移 MySQL 数据(推荐两

MyBatis-Plus逻辑删除实现过程

《MyBatis-Plus逻辑删除实现过程》本文介绍了MyBatis-Plus如何实现逻辑删除功能,包括自动填充字段、配置与实现步骤、常见应用场景,并展示了如何使用remove方法进行逻辑删除,逻辑删... 目录1. 逻辑删除的必要性编程1.1 逻辑删除的定义1.2 逻辑删php除的优点1.3 适用场景2.

Spring Boot基于 JWT 优化 Spring Security 无状态登录实战指南

《SpringBoot基于JWT优化SpringSecurity无状态登录实战指南》本文介绍如何使用JWT优化SpringSecurity实现无状态登录,提高接口安全性,并通过实际操作步骤... 目录Spring Boot 实战:基于 JWT 优化 Spring Security 无状态登录一、先搞懂:为什

JAVA SpringBoot集成Jasypt进行加密、解密的详细过程

《JAVASpringBoot集成Jasypt进行加密、解密的详细过程》文章详细介绍了如何在SpringBoot项目中集成Jasypt进行加密和解密,包括Jasypt简介、如何添加依赖、配置加密密钥... 目录Java (SpringBoot) 集成 Jasypt 进行加密、解密 - 详细教程一、Jasyp

Java通过ServerSocket与Socket实现通信过程

《Java通过ServerSocket与Socket实现通信过程》本文介绍了Java中的ServerSocket和Socket类,详细讲解了它们的构造方法和使用场景,并通过一个简单的通信示例展示了如何... 目录1 ServerSocket2 Socket3 服务器端4 客户端5 运行结果6 设置超时总结1

Java JAR 启动内存参数配置指南(从基础设置到性能优化)

《JavaJAR启动内存参数配置指南(从基础设置到性能优化)》在启动Java可执行JAR文件时,合理配置JVM内存参数是保障应用稳定性和性能的关键,本文将系统讲解如何通过命令行参数、环境变量等方式... 目录一、核心内存参数详解1.1 堆内存配置1.2 元空间配置(MetASPace)1.3 线程栈配置1.

MongoDB搭建过程及单机版部署方法

《MongoDB搭建过程及单机版部署方法》MongoDB是一个灵活、高性能的NoSQL数据库,特别适合快速开发和大规模分布式系统,本文给大家介绍MongoDB搭建过程及单机版部署方法,感兴趣的朋友跟随... 目录前言1️⃣ 核心特点1、文档存储2、无模式(Schema-less)3、高性能4、水平扩展(Sh

Mysql 驱动程序的程序小结

《Mysql驱动程序的程序小结》MySQL驱动程序是连接应用程序与MySQL数据库的重要组件,根据不同的编程语言和应用场景,MySQL提供了多种驱动程序,下面就来详细的了解一下驱动程序,感兴趣的可以... 目录一、mysql 驱动程序的概念二、常见的 MySQL 驱动程序1. MySQL Connector

MySQL中存储过程(procedure)的使用及说明

《MySQL中存储过程(procedure)的使用及说明》存储过程是预先定义的SQL语句集合,可在数据库中重复调用,它们提供事务性、高效性和安全性,MySQL和Java中均可创建和调用存储过程,示例展... 目录概念示例1示例2总结概念存储过程:在数据库中预先定义好一组SQL语句,可以被程序反复调用。