为什么要做体积优化
- 微信小程序发布主包限制大小为2M,超出无法发布
- 常见场景:日常开发打体验码大家会打开4M预览限制,本地预览是ok的,临近发布时,突然发现体积超了,阻塞发布,就会紧急处理一波,这样极其容易发生线上问题
怎么做优化
首先需要了解依赖分析
- 打开微信小程序ide,点击图示
- 目前是将整个项目打包到主包里,体积1.37M
- 可以点击主包,查看更详细内容分布
- 注意
修改配置重新编译后,微信ide体积分布会展示不准确,关闭后重新进入ide即可
分包加载
小程序推荐
采用分包
形式解决体积问题
分包概念
- 每个分包的
体积不可超出2M
- 分包不可引用其他分包内容,但可引用主包内容
- 主包不可引用分包内容
- 分包异步化可突破包之间的限制,实现任何包都可以访问分包
开始分包
-
在app.config.json中配置subpackages
-
以下为项目页面结构图示
-
目前我们有3个页面,pages/index/index为主页面,那么sub中的两个页面就可以放到分包中去
-
图示:将pages中目录去除,放到subpackages中
-
可以看到目前主包体积变小,增加了两个分包
疑问
:这俩分包合起来也没超过2M,为啥分开拆,不能合并到一起吗?答:
在微信和支付宝环境是可以的,但是在mpaas环境,一个分包只能放置一个页面,否则分包中的第二个页面跳转过去会白屏
组件的分包
- 现在出现了一个问题,业务代码中,通常是会有通用组件的,那么这个通用组件存在三种情况
- 主包分包都使用
- 多个分包使用
- 单个分包使用
- 这几种情况在项目中的体现还各不相同,
- 表现1:公共组件打包在主包
- 表现2:每个分包打包一份,taro会帮我们自动cv到使用目录
- 表现3:只有用到的分包打包一份
- 但是当作公共组件的初衷就是为了多方使用,taro虽然帮我们处理了,但会增加总体积,比如组件体积为1,两个分包都使用,那么总体积就是4
- 所以最佳方案应该是将组件真正的抽离,多方调用,而不是cv,那么我们先将组件打包为
自定义组件
,然后进行分包
- 这种方案小程序称为分包异步化
分包异步化
- 分包异步化简单来讲就是H5中异步加载的一种演变,在异步加载的过程中中,使用componentPlaceholder中指定的组件做替身(可以做loading),当资源加载好后进行自动替换
- 我们在index.config.js中增加usingComponents和componentPlaceholder配置项
usingComponents
- key要使用的组件别名
- value为组件地址(相对本文件即可)
componentPlaceholder
- key同上
- value为替补渲染标签或组件
{
usingComponents: {
'ccc-container': '../../scopeComponent/cccContainer/index',
},
componentPlaceholder: {
'ccc-container': 'view',
},
}
- 然后直接在页面里调用即可,usingComponents本身就是注册组件的意思,在页面级注册后,整个页面中都可以直接使用
<ccc-container />
- 现在dist目录中增加了scopeComponent目录,但是查看目录包体积划分可以看到这个文件目前还算在主包中,所以我们需要在app.config.js的subPackages增加一个配置
subPackages: [
{
root: 'scopeComponent',
pages: [],
},
]
组件抽离后存在的问题
- 抽离后可能会存在一定的样式问题,所以需要自行校对
- 可在自定义组件index同级目录增加index.config.js
export default {
component: true,
styleIsolation:'shared'
};
- 传参问题与组件调用模式
- 比如我是使用vue3开发,那么我肯定期望抽离出去的组件是可以想vue一样去props传参数的,而不是像真正的小程序那样传递,那仅仅按照上述步骤,是参数是失效的,组件永远拿不到
- 如何解决:
- package.json 的taro build命令增加 --new-blended,开启新混合模式
- 传递参数为props,不是直接传递,比如正常传递为a=1,b=2,现在为props={{a:1,b:2}}
- app.config.ts中配置components属性,value为自定义组件地址Array
- 图示:
新混合模式
方案目前官方只适配了react,在vue3使用会出现vue自定义组件不渲染的问题,已在github上反馈,应该是bug- 对比了下前后dist产物,发现vue3混合模式下自定义组件的导入函数有变化,应该是这里有问题
插件体积优化
- 开发过程中,可能会用到一些插件,那么这些插件通常是直接在app.config.js中直接注册,大概率会打包到主包中
- 而且微信ide的依赖分析检测不出来,我们在发布的时候就可能被卡住
- 可以选择结合分包异步化,将插件抽离到分包中
- 然后封装分包自定义组件,在自定义组件中调用plugin内容
- 正常运行代码调用自定义组件即可
app.config.js
// 原始写法
{
plugins:[xx]
}
// 分包写法
{
subPackages:[
{
root: 'aaa',
pages: ['index'],
plugins:[xx]
}
}
如何查看分包数量
在ide的控制台,可以看到目前有3个分包
预加载
如何配置?
配置preloadRule,指定某个分包资源提前加载
如何查看是否加载成功?
可以通过vconsole中的preloadSubpackages查看是否加载成功
预加载时机?
默认为当前页面ready后200ms
触发,可通过index.config.json中的handleWebviewPreload
参数调整
有什么限制?
同一批次预加载中,分包总体积不可超出2M
一些其他的点
base64链接过长,也会大量占用体积,可以改换成cdn