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

相关文章

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事件接着,

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

JSON Web Token在登陆中的使用过程

《JSONWebToken在登陆中的使用过程》:本文主要介绍JSONWebToken在登陆中的使用过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录JWT 介绍微服务架构中的 JWT 使用结合微服务网关的 JWT 验证1. 用户登录,生成 JWT2. 自定义过滤

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.