小程序闭坑之this.setData频繁渲染赋值错误

1,163 阅读2分钟

这是我参与8月更文挑战的第2天

setData

setData 是小程序开发中使用最频繁的接口,也是最容易引发性能问题的接口。在介绍常见的错误用法前,先简单介绍一下 setData 背后的工作原理。

工作原理

小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境。在架构上,WebView 和 JavascriptCore 都是独立的模块,并不具备数据直接共享的通道。当前,视图层和逻辑层的数据传输,实际上通过两边提供的 evaluateJavascript 所实现。即用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立环境。而 evaluateJavascript 的执行会受很多方面的影响,数据到达视图层并不是实时的。

常见的 setData 操作错误

1.频繁的去 setData

频繁的setData,webview的 JS 线程一直处理忙碌状态,逻辑层到页面层的通讯耗时上升,导致渲染结果时间过程,用户体验不好。所以避免频繁操作setData,接下来说说两次setData间隔很近遇到的问题。

2.避免每次 setData 都传递大量数据

项目中使用 setData 遇到的问题

1.业务场景及问题

业务场景为充值金额卡片选择功能,用户可选择金额或者输入金额

需求:

  • 选择卡片金额,展示卡片金额-点击立即充值
  • 输入框获得焦点,金额展示为0,可输入状态
  • 输入框输入金额,展示输入金额-点击立即充值
  • 输入框有金额,此时点击卡片,展示卡片金额-点击立即充值 问题:
  • 卡片和输入金额频繁切换,需要短时间内频繁使用setData更新展示值,切换卡片后,偶尔展示值赋值就会被变成之前的值。情况如下图

WeChata4471abcc02990e6f64c06f420df834e.png 点击卡片setData时候可以看到成功,但是马上又会闪回去原来的值。

2.解决方案
setTimeout(function(){
    that.setData({
        confirmAmount: amount
    })
},0)

使用setTimeout包裹每次卡片赋值,问题就解决了,但是点击卡片反馈还是感觉有些慢,不知道大佬还有没有更好的解决办法。