背景: 最近项目中使用到movable-view
来做一个拖拽排序的功能,等到功能都实现完成后到真机测试发现,拖拽动画在Android端存在严重的卡顿掉帧,及其不跟手,但是在IOS端却挺流畅。查阅Google发现也有相同的小伙伴有类似问题:小程序的移动拖动图片安卓太过卡顿如何解决
导致卡顿掉帧的原因
例如页面有 2 个元素 A 和 B,用户在 A 上做 touchmove 手势,要求 B 也跟随移动,movable-view
就是一个典型的例子。一次 touchmove 事件的响应过程为:
a、touchmove 事件从视图层(Webview)抛到逻辑层(App Service)
b、逻辑层(App Service)处理 touchmove 事件,再通过 setData 来改变 B 的位置
一次 touchmove
的响应需要经过2 次的逻辑层和渲染层的通信 以及一次渲染,通信的耗时比较大。此外setData
渲染也会阻塞其它脚本执行,导致了整个用户交互的动画过程会有延迟。
针对以上原因,微信小程序推出了WXS(WX Script)
,其作用是能够让逻辑代码在视图层(Webview)运行,通过减少数据在视图层和逻辑层之间的传输次数,进而达到优化的目的。具体参考:WXS
在Taro中使用WXS的优化实践
背景:由于目前Taro中还没有支持WXS(taro#2959),所以我在项目中不能直接编写WXS代码,让Taro帮我编译成WXML。所以得用点小技巧来实现,希望未来Taro能够支持WXS。如果你是使用原生小程序开发可以直接参考WXS来实现,如果是其他框架则可以参照本文章进行实践。
优化前的代码
优化前通过setState
来动态更新x,y
坐标值,从而利用movable-view
达到拖拽效果。
进行优化
首先需要去除掉movable-view
组件,因为无法使用movable-view
和WXS
来达到减少数据传输经过的路径次数,其次movable-view
是用CSS做的动画,我们可以用position:absolute
来代替,在WXS
中动态设置top&left
的值,达到movable-view
的效果。
其次在对应组件(使用到WXS
的组件或页面)的目录下创建一个move.wxs
的脚本文件,用于动态设置需要做动画的节点的top&left
坐标值。
如果你在编译时发现编译后的组件目录下没有move.wxs
文件,则可参考copy进行配置。来源taro#2959
最后在对应的JSX
下引入move.wxs
并且与touchmove
事件绑定。
Taro中使用存在的问题
作者编辑本文时,Taro对于WXS
并没有很好的支持,只能说勉强达到能用WXS优化帧率的目的。不过目前Taro也准备对其进行支持,请关注taro#2959
。作者后续也会持续关注Taro
对WXS
的支持进度。
在我使用WXS
时遇到需要使用callMethod
的场景(参考:WXS响应事件),来调用Taro
类组件中定义的方法,直接按官方的教程使用是不行的。需要像以下的方式很丑陋的使用,目前具体原因不知,估计Taro
对于没绑定事件的方法编译方式有所不同。
)
在线演示
经过上面的优化,在Android
机型上拖拽动画的流畅度会得到大幅度提升。大家可以扫下方的小程序码进行体验,流程如下:
- 扫描小程序码进入小程序
- 登陆小程序
- 在个人书库页面,扫描书籍后方的条形码添加几本书籍
- 长按书籍后进行拖拽
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。