底层框架
技术选型
Hybrid技术
- 小程序的架构要求:快!加载快、渲染快……
- 渲染界面的技术:Hybrid 技术,介于原生技术和web 技术之间。
- 若使用纯客户端原生技术,小程序代码需要与微信代码一起编包,跟随微信发版,这种开发节奏必然是不对的。所以小程序像Web 技术那样,有一份随时可更新的资源包放在云端,通过下载到本地,动态执行后即可渲染出界面。
- 若使用纯 Web 技术来渲染小程序,UI渲染跟 JavaScript 的脚本执行都在一个单线程中执行,这就容易导致一些逻辑任务抢占UI渲染的资源。所以,渲染层使用了多个WebView线程渲染,从而避免了单个WebView的任务过于繁重,让用户有更好的交互体验。
- 最终,小程序界面的大部分功能由Web多线程渲染技术实现,小部分功能由客户端原生能力实现。
小程序里的javaScript
- 小程序里可以写JavaScript,是因为客户端系统有JavaScript 解释引擎,在iOS下是用内置的 JavaScriptCore框架,在安卓则是用腾讯x5内核提供的JsCore环境。
- 小程序把JavaScript 代码放在了一个沙箱环境里,阻止了用户对DOM 的直接操作,小程序只提供纯JavaScript 的解释和执行环境。这是出于安全考虑的,比如我们使用window.location 可以跳转任意页面,就会带来一定的风险。
webView
- 小程序里直接使用HTML 搭建视图会有以下缺陷:
- 存在管控与安全问题
- 标签众多,增加理解成本
- 接口太底层,不利于快速开发
- 能力有限,会限制小程序的表现形式
- 基于以上问题,小程序设计了Exparser组件框架,它对html 的功能进行了封装。
原生组件
- 原生组件和普通view、text之类的组件相比,比较特殊,它的渲染还有微信客户端的参与,这就是小程序Hybrid技术的一个应用。
- 原生组件的优点:
- 扩展Web的能力。比如像输入框组件(input, textarea)有更好地控制键盘的能力。
- 体验更好,同时也减轻WebView的渲染工作。比如像地图组件(map)这类较复杂的组件,其渲 染工作不占用WebView线程,而交给更高效的客户端原生处理。
- 绕过setData、数据通信和重渲染流程,使渲染性能更好。比如像画布组件(canvas)可直接用一套丰富的绘图接口进行绘制。
性能优化
启动小程序
- 小程序启动时,微信会为小程序展示一个固定的启动界面,界面内包含小程序的图标、名称和加载提示图标。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/cacaed28825b3ae8be7bfb14a286cffc.png)
性能优化方式一:分包加载
- 采用分包加载时,小程序的代码包有两种:
- 一个“主包”,包含小程序启动时会马上打开的页面代码和相关资源。
- 多个“分包”,包含其余的代码和资源。
- 这样,小程序启动时,只需要先将主包下载完成,就可以立刻启动小程序,从而降低小程序代码包的下载时间。
- 分包app.json 中的配置如下
{
"pages":["pages/index/index","pages/logs/logs"],
"subPackages": [
{
"root": "packageA",
"pages": [“pages/apple/apple"]
}, {
"root": "packageB",
"pages": ["pages/banana/banana"]
}
]
}
- 单个分包/主包大小不能超过 2M
- 整个小程序所有分包大小不超过 16M
性能优化方式二:控制代码包大小
- 精简代码,去掉不必要的WXML结构和未使用的WXSS。
- 减少在代码包中直接嵌入的资源文件。不是必须的可以放在服务器上。
- 压缩图片,使用适当的图片格式。
页面及页面层级
性能优化方式三:合理使用wx.navigate
- 一个页面的多次显示,并不会使得这个页面的JS文件被执行多次,我们可以利用这个特性,建立基于页面的全局变量。
- wx.navigateTo 方法会重新实例化目标页面的Page构造器。
例如,页面A使用wx.navigateTo 跳转到页面B,再使用wx.navigateTo跳转到页面A,页面A中的Page构造器就会被重新实例化 - wx.navigateBack 方法不会重新实例化目标页面的Page构造器,但它会销毁当前页面。
- 在视图层内,小程序的每一个页面都独立运行在一个页面层级上。
- 小程序启动时仅有一个页面层级,每次调用wx.navigateTo,都会新建一个页面层级;
相对地,wx.navigateBack会销毁一个页面层级,并且不会再重新实例化返回页的Page构造器。 - 对于每一个新的页面层级,视图层都需要进行一些额外的准备工作。
- 在小程序启动前,微信会提前准备好一个页面层级用于展示小程序的首页。
- 除此以外,每当一个页面层级被用于渲染页面,微信都会提前开始准备一个新的页面层级,使得每次调用wx.navigateTo 都能够尽快展示一个新的页面。
数据通信
- 在每个小程序页面的生命周期中,存在着若干次页面数据通信:
- 逻辑层向视图层发送页面数据(setData)
- 视图层向逻辑层反馈数据和用户事件 (data-key、bind:*)
性能优化方式四:js中提高数据更新速度
- 多次setData合并成一次setData调用,不要过于频繁调用setData。
- 数据通信的性能与数据量正相关,因而如果有一些数据字段不在界面中展示,且数据结构比较复杂或包含长字符串,则不应使用setData来设置这些数据。
- 与界面渲染无关的数据最好不要设置在data中,可以考虑设置在page对象的其它字段下。
- 例如
onShow: function() {
this.setData({ a: 1 })
this.setData({ b: 2 })
this.setData({ a: 1, b: 2 })
this.setData({myData: {a: '这个字符串在WXML中用到了',b: '这个字符串未在WXML中用到,且很长…’ }})
this.setData({'myData:{a': '这个字符串在WXML中用到了'})
this._myData = {b: '这个字符串未在WXML中用到,且很长…'}
}
性能优化方式五:wxml 中提高数据更新速度
- 去掉不必要的事件绑定(
WXML中的bind和catch
),从而减少通信的数据量和次数。 - 不要在节点的data前缀属性中放置过大的数据,因为事件绑定时需要传输
target和currentTarget的dataset