评论

wepy脏检查原理、具体实现和实际应用

wepy的脏检查会在函数运行周期结束后调用,即便在函数内多次进行数据修改最后也只会执行一次setData,不需要担心多次setData带来的性能问题

前言

为什么要做脏检查?

  小程序是双线程的,它的渲染线程和脚本线程是分开的,意味着小程序页面不会像普通网页脚本运行时间过长导致阻塞页面的问题。但是两个线程并不是毫不相干,小程序页面的渲染需要的动态数据在脚本线程,这时候两个线程就需要进行通信来动态更新页面展示的数据,所以小程序提供setData的接口来帮助两个线程进行通信,这也是小程序调用的最频繁的接口。

  为什么频繁调用setData会有问题?因为两个线程之间传递的数据是字符串的形式,收到传递过来的数据需要把字符串转为脚本执行,当频繁setData的时候,渲染线程一直在编译执行渲染,导致视图的用户操作不能及时传到逻辑层,看起来页面就会像卡顿一样响应变慢。同样,setData大量数据也会造成同样的问题,因为setData大量数据意味着编译执行的时间变长,视图更新变慢。

  wepy使用脏检查对setData进行封装一是不需要手动去进行setData数据更新页面,更方便地修改数据;另外,wepy的脏检查会在函数运行周期结束后调用,即便在函数内多次进行数据修改最后也只会执行一次setData,不需要担心多次setData带来的性能问题。

wepy脏检查原理及其实现

  了解了setData的原理后,来了解wepy的脏检查原理以及wepy是如何实现脏检查的。首先看一幅官方提供的执行脏数据检查的流程图。

wepy脏数据检查流程解读

  首先wepy通过$$phase标记当前是否在进行脏数据检查,以此保证只有一个脏数据检查流程在运行。这个时候如果有另外的脏检查调用则把$$phase赋值为'$apply',不执行脏数据检查流程。脏检查流程结束后会根据$$phase === '$apply'判断是否存在下一个脏数据检查流程,存在则再次进行脏数据检查流程。

  wepy脏数据检查过程一开始会把$$phase赋值为'$digest'标记当前正在进行脏数据检查状态,然后遍历数据列表的所有数据进行新旧值比对,将新旧值不相等的新值放到readyToSet对象中,然后使用readyToSet对象进行setData渲染页面,最后通过$phase判断是否还存在脏数据检查流程,存在则再次进行脏数据检查。

wepy脏数据检查源码

$apply的封装:脏检查的调用

$digest的封装:脏检查的流程

流程准备:

检查过程:
computed对象的脏值检查:

上面这里可以看到每次执行脏检查流程遍历computed对象属性都会执行val = fn2.call(this),意味着每次脏检查流程总是会执行一遍computed对象属性里面的方法,这里也对应到下面wepy官网上面的一段话。所以避免在computed里面做耗时长的计算,以免加长脏检查流程的时间,延缓setData渲染视图更新。

data对象的脏值检查

watch监听处理:

上面可以看到的是脏检查流程中对watch的处理,第一个this.watch[k].call(this, this[k], originData[k]) 可以理解是调用watch对应属性的监听方法,第二个是表示watch对应属性的值不是一个函数而是一个字符串的时候,会去看methods是否存在同名属性的方法,存在则调用methods的同名方法,这个处理看起来就是watch和methods方法公用,示例代码如下。


watch = {



    A: 'String'

}



methods = {



    A(newValue, oldValue) {



    }

}

组件props数据处理:

父子组件双向绑定的数据的处理:

这里主要是看脏检查流程是在父组件触发还是子组件触发,判断数据更新的来源,然后根据数据的更新来源来进行父子组件双向绑定数据的同步更新。

流程结束:

wepy如何调用脏检查?

在文章的开头讲到wepy会在函数运行周期结束后调用,那么wepy到底是怎样调用的呢?

1.wepy对生命周期都进行了一层封装,在函数的后面调用了page.$apply()执行脏检查

2.wepy封装了$bindEvt方法,对非onLoad、onShow等生命周期事件进行了进一步封装,详细看wepy源码base.js文件

总结

  由于wepy脏检查是在函数运行周期结束时调用的,所以在函数内使用异步函数promise或者async/await的时候需要自己手动的调用$apply()执行脏检查,否则函数运行周期结束后调用$apply()此时异步函数还没有执行完毕。总的来说,wepy脏检查在做的两件事就是检测脏值和同步更新数据。

参考文章和网站:

  1. 小程序官方优化建议https://developers.weixin.qq.com/miniprogram/dev/framework/performance/tips.html

  2. wepy官网-wepy数据绑定方式

https://tencent.github.io/wepy/document.html#/

最后一次编辑于  2019-06-11  
点赞 3
收藏
评论

2 个评论

  • hallstatt
    hallstatt
    2019-06-27

    写的真好!受益匪浅!

    2019-06-27
    赞同
    回复
  • \
    \
    2019-06-11

    又打广告

    2019-06-11
    赞同
    回复
登录 后发表内容