支付宝小程序优化策略

233 阅读2分钟

一.体积优化

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

  1. 减少使用同步阻塞api,尽量使用异步的,如:my.setStorageSync - my.setStorage
  2. 设置缓存,如:getSystemInfogetSystemInfoSync等不变的信息,可进行缓存;减少调用次数
  3. 减少jsapi并发调用,参见前两项

setData

api种类:

  1. Page.prototype.setData(data: object, cb: function)
  2. Page.prototype.$spliceData(data: object, cb: function) 发送数据到视图,长列表更具有优势
  3. Component.prototype.setData(data: object, cb: function)
  4. Component.prototype.$spliceData(data: object, cb: function)
  5. Page.prototype.$batchUpdates(cb: Function) 合并更新
  • 减少调用次数 < 20次/s,非用户触发
  • 数据量不宜过大(序列化和反序列化) < 256kb
    • 减少数据量,一次性避免传过长列表
    • 分批处理,使用$spliceData传输
    • 根据业务情况,手动调用$batchedUpdates来合并多次调用
    • 必须频繁触发,则封装成组件,定时器,onscroll等,在组件级别的进行触发