前言
没有理论,只有实操,用最直接的方式来了解和使用小程序分包。
文章偏向使用taro来模拟小程序分包配置,在原生小程序中也是几乎差不多的配置方式。
为什么要有小程序分包?
因为上传小程序打包以后的代码包不可以超过2M。但我们在开发小程序的时候需要加载某些依赖或者一下静态图片,代码包难免超过2M。所以需要小程序分包功能将小程序中所有的代码分别打到不同的代码包里去,避免小程序只能上传2M的限制。
目前小程序分包大小有以下限制:
- 整个小程序所有分包大小不超过 20M(开通虚拟支付后的小游戏不超过30M)
- 单个分包/主包大小不能超过 2M
如何对小程序进行分包?
本质上就是,配置一下app.json(小程序)或app.config.ts(Taro)中的subpackages字段。注意,分包的这个root路径和原本的pages是同级的。
如下图
这样配置好了,最基本的分包就完成了。
如何配置多个子包?
subpackages是个数组,在下面加上一样的结构就好了。
如何判断分包是否已经生效?
打开微信开发者工具,点击右上角详情 => 基本信息 => 本地代码,展开它。出现 主包,/xxxx/就是分包生效了。
如下图
所有页面都可以打到分包里面吗?
也不是,小程序规定,Tabbar页面不可以,一定需要在主包里。否则他直接报错。
分包中的依赖资源如何分配?
我们先来了解一下小程序分包资源
ruby
引用原则
`packageA` 无法 require `packageB` JS 文件,但可以 require 主包、`packageA` 内的 JS 文件;使用 [分包异步化](https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages/async.html) 时不受此条限制
`packageA` 无法 import `packageB` 的 template,但可以 require 主包、`packageA` 内的 template
`packageA` 无法使用 `packageB` 的资源,但可以使用主包、`packageA` 内的资源
原因: 分包是依赖主包运行的,所以主包是必然会被加载的,所以当分包引用主包的时候,主包的相关数据已经存在了,所以可以被引用。而分包不能引用其他分包的数据,也是因为加载顺序的问题。如果分包A引用分包B的数据,但分包B尚未被加载,则会出现引用不到数据的问题。
如果主包和分包同时使用了一个依赖,那么这个依赖会被打到哪里去?
会被打到主包
因为主包不能引用分包的资源,但是子包可以引用主包的资源,所以为了两个包都能引用到资源,只能打到主包中
比如以下情况
分包和主包同时使用了dayjs,那么这个依赖会被打入到主包中。
如果某一个依赖只在分包中使用呢?
如果某一个资源只在某一个分包中使用,那就会被打入到当前分包。
如果两个子包同时使用同一个资源呢?那资源会被打进哪里。
主包,因为两个子包的资源不能互相引用,所以与其给每一个子包都打入一个独立资源。小程序则会直接把资源打到主包中,这样,两个子包就都可以使用了。
分包需要担心低版本的兼容问题吗
不用
由微信后台编译来处理旧版本客户端的兼容,后台会编译两份代码包,一份是分包后代码,另外一份是整包的兼容代码。 新客户端用分包,老客户端还是用的整包,完整包会把各个 subpackage
里面的路径放到 pages 中。
独立分包
什么是独立分包
顾名思义,独立分包就是可以独立运行的分包。
举个例子,如果你的小程序启动页面是分包(普通分包)中的一个页面,那么小程序需要优先下载主包,然后再加载普通分包,因为普通分包依赖主包运行。但是如果小程序从独立分包进入进入小程序,则不需要下载主包,独立分包自己就可以运行。
普通分包所有的限制对独立分包都有效。
为什么要有独立分包,普通分包不够吗
因为独立分包不需要依赖主包,如果有作为打开小程序的的入口的必要,加载速度会比普通分包快,给客户的体验感更好。毕竟谁也不想打开一个页面等半天。
举个例子,如果小程序启动的时候是打开一个普通分包页面。则加载顺序是:加载主包 => 再加载当前分包
但如果小程序启动的时候是打开一个独立分包页面,则加载顺序是:直接加载独立分包,无需加载主包。
独立分包相对于普通分包,就是省去了加载主包的时间和消耗。
独立分包如何配置
配置和普通分包一样 ,加一个independent属性设为true即可。
独立分包的缺点
既然独立分包可以不依赖主包,那我把每个分包都打成独立分包可以吗。
最好别那么干
理由有四点
1.独立分包因为不依赖主包,所以他不一定能获取到小程序层面的全局状态,比如getApp().也不是完全获取不到,主包被加载的时候还是可以获取到的。概率性出问题,最好别用。
2.独立分包不支持使用插件
3.小程序的公共文件不适用独立分包。比如Taro的app.less或小程序的app.wxss
上述三个,我觉的都挺麻烦的。所以不是作为入口包这种必要的情况下,确实没有使用独立分包的需求。
PS:一个小程序里可以有多个独立分包
独立分包有版本兼容问题吗
有滴,但你不用这个兼容问题直接让你报错 , 在低于 6.7.2 版本的微信中运行时,独立分包视为普通分包处理,不具备独立运行的特性。
所以,即使在低版本的微信中,也只是会编译成普通分包而已。
注意!!! 这里有一个可能会遇到的坑,就是如果你在独立分包中使用了app.wxss或者app.less这些小程序层面的公共css文件,那么在低版本(<6.7.2)进行兼容的时候,你就会发现,独立分包的页面会被这些全局的CSS影响。因为那时候独立分包被编译成了普通分包。而普通分包是适用全局公共文件的。
分包预下载
首先我们需要了解,分包是基本功能是,在下程序打包的时候不去加载分包,然后在进入当前分包页面的时候才开始下载分包。一方面目的是为了加快小程序的响应速度。另一方面的原因是避开微信小程序本身只能上传2M的限制。
这里有一个问题,就是我在首次跳转某个分包的某个页面的时候,出现短暂的白屏怎么办?(下载分包的时间+运行接口的时间+渲染视图的时间)。
后两者没法彻底避免,只能优化代码,第一个下载分包的时间可以使用分包预下载功能解决。
我们可以通过分包预下载在进入分包页面之前就开始下载分包,来减少进入分包页面的时间。
如何配置分包预下载
当前的分包预下载只能在app.config(Taro)或者app.json(原生小程序)通过preloadRule字段去配置。
preloadRule字段是一个对象,key是页面的路径,value是进行预加载的分包name或者key,__APP__
代表主包
上案例
通过preloadRule字段去配置
"packageB/pages/user/index"是key
packages:["packageA"]是value
案例上的意思是当进入packageA分包的时候,开始下载分包packageB
如果要某一个分包在加载主包的就开始下载,那么就设置packages:["APP"]即可。
总结
- 分包是为了解决小程序超过2m无法上传的问题
- 分包依赖于主包,进入分包页面,主包必然需要优先被加在
- 主包和分包同时引用一个依赖或资源,则当前依赖或资源会被打入到主包
- 两个分包使用了同一个依赖或资源,则该依赖和资源会被打入到主包
- 某资源或依赖只在某一个分包中使用,则该资源和依赖会被打入到该分包中
- 独立分包的配置相对于普通分包只是多了一个independent字段,设置为true
- 独立分包无需依赖主包,可独立加载。
- 独立分包中谨慎使用全局属性,最好别用,可能获取不到
- 分包可以被预加载,用于解决进入分包页面时才开始加载分包导致页面可能出现的(取决于加载速度)短暂白屏的问题。
如果您认为对您有用的话,留个赞或收藏一下吧~