深入理解小程序—— 小程序探索中的数据
研究背景
上一篇文章了解了小程序的生命周期。接下来,我将研究数据通信。我觉得生命周期和数据通信可以清楚地控制整个程序。定位和解决问题的能力将大大提高。
当我第一次开始撸小程序时,我觉得我可以查看文档,这导致编写了大量的垃圾代码坑。我相信大多数初学者都不会仔细研究这些文件,更不用说指南了。在阅读了小程序的官方指南后,我觉得有必要总结初学者,教学和学习
天生的延时为了解决管控与安全问题,小程序提供了一个沙箱环境来运行开发者的JavaScript 代码基于双线程模型,意味着任何数据传递都是线程间的通信在小程序架构里,这一切都会变成异步异步会使得各部分的运行时序变得复杂一些,因此逻辑层与渲染层需要有一定的机制保证时序正确这些工作在小程序框架里会处理好,开发者沈阳软件定制
只需了解生命周期并控制更新UI的正确时机。在上一篇文章中,我们学习了小程序的生命周期。本文主要了解如何控制更新UI
如何控制合适的时机更新UI
的适当时机 小程序作为MVVM框架的一员,数据驱动是核心,数据是世界上最好的
要理解数据通信和生命周期,操作机制是不可分割的,如双线程通信模型,数据驱动,底层框架,界面渲染机制等,本文将不再介绍,也不能比它更好。官方文档,更多实时,本文主要理解以下几点:(思考了很长时间,总结如下)1。小程序中的数据范围2.合理的操作数据,提高了性能3.数据通信之间组件4.缓存数据5,扩展状态管理Westore在此之前,还有一些官方图片,有一个后续理解的概念
明确几点概念渲染层和数据相关逻辑层负责产生、处理数据,小程序的JS脚本运行在同一个JsCore线程里逻辑层和渲染层是一对多的关系,但页面对象(page)和页面层级(webview)一一对应
一、小程序中数据的作用域
1、全局数据// app.jsApp({ globalData: 'I am global data' // 全局共享数据})// 其他页面脚本other.jsvar appInstance = getApp()console.log(appInstance.globalData) // 输出: I am global dataApp实例是单例的,因此不同页面直接可以通过App实例下的属性来共享数据
2、页面共享数据简单来说就是页面所在的JS中Page构造器外定义的变量执行如下示例代码以验证console.log('加载 page.js')var count = 0Page({ onLoad: function() { count += 1 console.log('第 ' + count + ' 次汇海这个页面') }})你会发现小程序汇海时,打印了'加载 page.js',每次打开这个页面,count变量会递增,不会随着页面的销毁而销毁由于页面所在的JS文件、app.js和所有其他被require的JS文件,在小程序汇海时自动执行并被基础库注册,所以逻辑层(看作所有js的集合)只执行一次,之后都是通过Page构造器创建Page实例来渲染页面一般require的依赖或者第三方库JS以及getApp(),我们都会放在页面共享的数据中
3、Page实例中的数据也就是每个Page构造器中的数据,没错!这就是我们每天搬砖的地方Page({ data: { text: "我用来改变界面显示" }, onLoad: function(options) { }, onReady: function() { }, onShow: function() { }, onHide: function() { }, onUnload: function() { }, text: "我不显示在页面上", myData:{ a: '我也不显示在页面上', b: true }})大家应该都知道data中的数据用来渲染页面,和VUE一样,不过VUE中只要写this.text,而小程序中要写this.data.text,每次写到这个就郁闷,其实与界面渲染无关的数据最好不要设置在data中,对性能也是大有好处
4、自定义组件中的数据properties外部传值data内部数据emmmmmm自定义组件有必要另开一篇总结
二、合理操作数据,提升性能
数据通信页面初始数据通信:视图层在接收到初始数据data时,进行初始渲染更新数据通信:视图层在接收到更新数据setData时,进行重渲染用户事件通信:一个用户事件被触发,视图层会将信息反馈给逻辑层一切都是2个线程通信的结果,数据量小于64KB时总时长可以控制在30ms内。传输时间与数据量大体上呈现正相关关系,传输过大的数据将使这一时间显著增加。因而减少传输数据量是降低数据传输时间的有效方式
提升性能须遵循的原则
当调用setData执行重新呈现时,视图层将数据和setData数据应用于WXML片段以获取新节点树,然后将其与当前节点树进行比较,以便需要更新哪些节点的节点,需要添加或删除哪些节点,最后将setData数据合并为数据,并将旧节点树替换为新节点树,以便下次重新渲染。
可以看出,当逻辑层setData将数据发送到更新视图时,它需要两个线程的一些通信消耗,并且不会传播数据,只有一个脑通过,生成新的节点树,并且每个通信都需要传输,生成和比较。合并
为了提升数据更新的性能,最好遵循以下原则:1、不要过于频繁调用setData,应考虑将多次setData合并成一次setData调用2、数据通信的性能与数据量正相关,每次只设置需要改变的最小单位数据3、与界面渲染无关的数据最好不要设置在data中,可以考虑设置在page对象的其他字段下
其他优化策略:1、去掉不必要的事件绑定(WXML中的bind和catch),从而减少通信的数据量和次数2、事件绑定时需要传输target和currentTarget的dataset,因而不要在节点的data前缀属性中放置过大的数据3、精简代码,降低WXML结构和JS代码的复杂性,必要时使用分包优化
注意:直接修改 Page实例的this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致不要把data中的任意一项的value设为undefined,否则可能会有引起一些不可预料的bug
三、组件间的数据通信
组件区分业务组件和纯组件业务组件与业务数据紧耦合,换一个项目可能该组件就用不上,除非非常类似的项目业务组件和页面一样通过 全局变量 获得所需参数,通过更改 全局变量 与外界通讯业务组件也可以通过 props 获得所需参数,通过 triggerEvent 与外界通讯纯组件与业务数据无关,可移植和复用纯组件只能通过 props 获得所需参数,通过 triggerEvent 与外界通讯
四、缓存数据
本地数据缓存是存储在当前设备硬盘上的小程序数据。 小程序主机环境将缓存空间与不同的小程序和不同的用户维度隔离开来。每个小程序缓存空间的上限为10MB
缓存充当全局数据通过wx.getStorage/wx.getStorageSync读取本地缓存通过wx.setStorage/wx.setStorageSync写数据到缓存
利用本地缓存提前渲染界面我们在拉取商品列表后把列表存在本地缓存里在onLoad发起请求前,先检查是否有缓存过列表如果有的话直接渲染界面等到wx.request的success回调之后再覆盖本地缓存重新渲染新的列表Page({ onLoad: function() { var that = this var list =wx.getStorageSync("list") if (list) { // 本地如果有缓存列表,提前渲染 that.setData({ list: list }) } wx.request({ url: 'https://test.com/getproductlist', success: function (res) { if (res.statusCode === 200) { list = res.data.list that.setData({ // 再次渲染列表 list: list }) wx.setStorageSync("list",list) // 覆盖缓存数据 } } }) }})一般在对数据实时性/一致性要求不高的页面采用这个方法来做提前渲染,用以优化小程序体验
五、扩展-状态管理westore
参考
现在主流MVVM框架如vue/react/angluar都有状态管理,小程序也可以有,由于小程序的实时特性,迭代更新速度非常快,所以对于小程序我主张原始开发,但是多端也是非常好的解决方案,当然,尝试播放dcloud uniapp废话,直接地图和链接,有兴趣自学,Westore的解决方案:
Westore项目地址
“沈阳软件公司”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与
我们联系删除或处理,客服QQ:55506560,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同
其观点或证实其内容的真实性。
热门文章
使用“扫一扫”即可将网页分享至朋友圈。