上个月接手一个电商类小程序项目,客户反馈说提审老是失败,原因很简单——主包体积超了。打开项目一看,所有页面、组件、图片资源全塞在主包里,构建产物直接飙到12MB。
问题根源:所有东西都往主包塞
这个项目最初是一个人写的,没做任何分包规划。首页、商品详情、购物车、个人中心、订单列表、售后流程……几十个页面全在pages目录下。再加上引入了完整的UI组件库和未压缩的本地图片,体积失控是必然的。
分包策略设计
微信小程序的分包规则其实不复杂:主包放tabBar页面和公共资源,其他按业务模块拆成独立分包。但真正动手拆的时候,麻烦事不少。
我按业务域划分了四个分包:商品模块(goods)、订单模块(order)、营销模块(marketing)、用户模块(user)。app.json里的subpackages配置大致是这样的结构,每个分包指定root路径和对应的pages列表。
独立分包的坑
最初我把营销活动页设成了独立分包(independent: true),想着活动页可以独立运行不依赖主包下载。结果发现活动页里用了app.wxss的全局样式和app.js里的公共方法,独立分包是访问不到这些的。解决办法是把活动页需要的样式单独抽了一份,公共方法通过分包内的util文件复制一份过去。虽然有点冗余,但独立分包的启动速度确实快了不少。
分包预下载配置
用户从首页点进商品详情的时候,如果商品分包还没下载完,会有明显的白屏等待。preloadRule可以解决这个问题——在用户进入首页时就预下载商品分包。配置方式是在app.json里加preloadRule字段,指定network为wifi或all,packages填对应分包名。实测在WiFi环境下,预下载基本能在用户浏览首页的1-2秒内完成,点进商品页几乎无感。
图片资源处理
分包只能解决代码和页面的体积问题,图片资源才是大头。项目里有大量商品分类图标和营销banner直接放在本地。我的做法是:图标类用iconfont替代,banner和大图全部上传到CDN,代码里改为网络地址。这一步直接砍掉了将近6MB的体积。
最终效果
重构完成后,主包体积控制在1.8MB,四个分包各在1-3MB之间,总包体积也从12MB降到了8MB左右。提审一次通过,首屏加载时间从4秒多降到1.5秒。
几个实操建议:项目初期就规划好分包结构,别等体积超了再拆,成本会高很多;tabBar页面必须在主包,这个改不了,所以tabBar别设太多页面;分包之间不能互相引用组件,公共组件要么放主包要么每个分包各放一份;构建时开启"上传时压缩代码"选项,能再省10%-15%的体积。