支付宝小程序扩展能力 附录 1:优化 setData 逻辑方案明细

2020-09-19 10:44 更新

优化 setData 逻辑

任何页面变化都会触发 setData,同一时间可能会有多个 setData 触发页面进行重新渲染。如下四个接口都会触发 web-view 页面重新渲染。

  • Page.prototype.setData:触发整个页面做差异比较;
  • Page.prototype.$spliceData:针对长列表做优化,避免每次传递整个列表,触发整个页面做差异比较;
  • Component.prototype.setData:只会从对应组件节点开始做差异比较;
  • Component.prototype.$spliceData:针对长列表做优化,避免每次传递整个列表,只会从对应组件节点开始做差异比较。

优化建议

  • 避免频繁触发 setData 或者 $spliceData,不管是页面级别还是组件级别。在我们分析的案例中,有些页面有倒计时逻辑,但是有的倒计时过于频繁触发(ms 级别的触发);
  • 需要频繁触发重新渲染时,避免使用页面级别的 setData 和 $spliceData, 将这一块封装成自定义组件,然后使用组件级别的 setData 或 $spliceData 触发组件重新渲染;
  • 长列表数据触发渲染时,使用 $spliceData 多次追加数据,而不用传递整个列表;
  • 复杂页面建议封装成自定义组件,减少页面级别的 setData。

优化案例

推荐指定路径设置数据

this.setData({
  'array[0]': 1,
  'obj.x':2,
});

不推荐如下用法(虽然拷贝了this.data, 仍然直接更改了其属性)

const array = this.data.array.concat();
array[0] = 1;
const obj={...this.data.obj};
obj.x=2;
this.setData({array,obj});

更不推荐直接更改 this.data(违反不可变数据原则)

this.data.array[0]=1;
this.data.obj.x=2;
this.setData(this.data)

长列表使用 $spliceData

this.$spliceData({ 'a.b': [1, 0, 5, 6] })

注意

有时业务逻辑封装到了组件中,当组件 UI 需要重新渲染时,只需在组件内部调用 setData。但有时需要从页面触发组件重新渲染,比如在页面上监听了 onPageScroll 事件,当事件触发时,需要通知对应组件重新渲染,此时的处理措施如下所示:

// pages/index/index.jsPage({
    onPageScroll(e) {
        if (this.xxcomponent) {
            this.xxcomponent.setData({
                scrollTop: e.scrollTop            })
        }
    }
})
// components/index/index.jsComponent({
    didMount(){
        this.$page.xxcomponent = this;
    }
})

可在组件的 didMount 中将组件挂载到对应的页面上,即可在页面中调用组件级别的 setData 只触发组件重新渲染。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号