一.体积优化
1.图片等静态资源
- 放到服务器
- 小图片使用雪碧图/iconfont
- 同域名耗时300ms的图片请求,最多同时并发6个图片请求
- 屏幕外图片懒加载,设置image,lazy-load="{{true}}"
- 启动阶段网络请求图片 < 10个,引起抖动,重排,重绘;开启http图片缓存
2.分包加载
提升首次打开速度 ,不经常使用页面放到子包中,访问到再加载,首次下载主包体积减小,提升下载速度;
- 1个主包 < 2m 启动+tabbar+公共资源,建议保留核心页面
- n个子包 < 8m
- 根据开发者的配置,打包成不同子包
- 配置:app.json中的subPackages字段,subPackages配置外的目录,将默认打包到主包中;
- 分包仅仅可以引用自身+主包资源;
- 分包/主包独立打包,同一个js模块会重复打进子包和主包,
如果需要配置将同一个js模块,主包分包共享,配置subPackageBuildType: shared,
将重复js模块打入主包
"subPackages": [{
"root": "test",
"pages": [
"pages/page1",
"pages/page2"
]
}]
3.分包预下载
进入页面时,预下载资源
app.json中配置preloadRule
字段,key为页面路径,value为{packages: root名称,network?: 'wifi' | 'all'}
"preloadRule": {
"pages/index": {
"packages": ["test"],
"network": "wifi"
}
}
配置以后,在访问pages/index路由的时候,就会预先下载test子包的资源
二.代码结构优化
1.插件
插件系统,插件是独立的,可任意用到小程序中,插件在打包的时候,不会打包进去,在启动的时候,实时下载,但是体积会被计算到主包中去,就算是分包使用的插件,也会被计入到主包中去,因此,插件只能作为代码分割/向外提供公用服务的方法,不能作为优化方法,而微信提供的直播插件,不会被计入主包体积;
1.1动态插件
无需在app.json中提前声明插件名称/路径,仅需要app.json中加入:"useDynamicPlugins": true使用的时候
,在使用时候
my.loadPlugin({
plugin: '2019235609092837@*', // 指定要加载的插件id和版本号,为*时则距离上次拉包超过24小时会拉取最新版本
success: () => {
const plugin = requirePlugin('dynamic-plugin://2019235609092837');
plugin.helloApi(); // 调用所引用插件的api。此处helloApi为api示例名称,请开发者自行替换为实际调用api名称
this.setData({ isReady: true }); // 插件已加载,可以渲染插件组件了
},
});
定位插件中国某个页面:dynamic-plugin://插件id/页面名称
1.2静态插件
需要在app.json中的plugins字段中声明所有需要用到的插件,然后,使用时,在.json文件中,usingComponents: {名称:插件地址},指明插件名称,才可使用,参考下方链接
opendocs.alipay.com/mini/plugin…
运行速度优化
lazyCodeLoading
小程序启动过程中,下载后,默认会执行所有代码,开启lazyCodeLoading: "requiredComponents",仅执行当前页面所需脚本+自定义组件脚本,对耗时可以有优化;
workers
将计算量大/异步耗时较长的放到worker线程当中;在app.json中声明有哪些worker,在使用到的地方,my.createWorker(worker入口文件绝对路径);worker中含有全局变量worker,可以postMessage
{
"workers": [
"workers/request/index.js",
"workers/response/index.js"
]
}
// 使用
const worker = my.createWorker(workers/request/index.js");
worker.onMessage((data) => console.log(data));
// worker中,此处为全局变量worker
worker.postMessage("test");
worker.terminate();
jsapi
- 减少使用同步阻塞api,尽量使用异步的,如:my.setStorageSync - my.setStorage
- 设置缓存,如:
getSystemInfo
、getSystemInfoSync
等不变的信息,可进行缓存;减少调用次数 - 减少jsapi并发调用,参见前两项
setData
api种类:
- Page.prototype.setData(data: object, cb: function)
- Page.prototype.$spliceData(data: object, cb: function) 发送数据到视图,长列表更具有优势
- Component.prototype.setData(data: object, cb: function)
- Component.prototype.$spliceData(data: object, cb: function)
- Page.prototype.$batchUpdates(cb: Function) 合并更新
- 减少调用次数 < 20次/s,非用户触发
- 数据量不宜过大(序列化和反序列化) < 256kb
- 减少数据量,一次性避免传过长列表
- 分批处理,使用$spliceData传输
- 根据业务情况,手动调用$batchedUpdates来合并多次调用
- 必须频繁触发,则封装成组件,定时器,onscroll等,在组件级别的进行触发