小程序 2MB 主包塞不下?18 个分包 + 首页预加载,冷门页面全踢出主包
小程序有个 2MB 主包硬限制现在放开到 4MB 也得悠着用招聘小程序功能越加越多提现、积分、会员、简历、企业认证……全堆主包打包直接报警。后来按高频留主包、低频进分包切了18 个分包根首页再配预加载首屏秒开。今天把分包怎么切、预加载怎么配、还有几个坑讲清楚。分包结构低频页面全踢出去主包只留 tabBar 页面和启动依赖其他全按业务域拆分包。pages.json里长这样{pages:[{path:pages/index/index,style:{navigationBarTitleText:首页}},{path:pages/job/list,style:{navigationBarTitleText:职位}},{path:pages/my/my,style:{navigationBarTitleText:我的}}],subPackages:[{root:pages/finance,pages:[{path:withdraw,style:{navigationBarTitleText:提现}},{path:balance,style:{navigationBarTitleText:余额明细}}]},{root:pages/integral,pages:[{path:index,style:{navigationBarTitleText:积分中心}},{path:detail,style:{navigationBarTitleText:积分明细}}]}// finance/integral/vip/resume/fair/job/user/auth/invite/poster/company/hr/message/common/my/apply/assessment/news]}原则就一条用户不天天进、启动不依赖的页面全走分包。提现、积分、VIP 开通、简历编辑、企业认证这些低频操作放分包主包瘦下去一半。首页预加载点到哪提前备好哪分包有个痛点首次进分包页面要现下载分包代码用户从首页点进职位会卡一下。preloadRule就是干这个的{preloadRule:{pages/index/index:{network:all,packages:[pages/job,pages/common]}}}首页加载时顺带把pages/job职位列表和pages/common公共组件/工具两个分包预载到本地。用户从首页跳职位分包已经在本地了秒开。network: all表示 WiFi 和流量下都预载想省流量可以写wifi。跳转分包页面的正确姿势分包页面跳转有个大坑uni.navigateTo的 url必须带分包根前缀// 正确完整路径带分包 rootuni.navigateTo({url:/pages/finance/withdraw});// 错误不带 root找不到页面直接跳失败uni.navigateTo({url:/pages/withdraw});还有uni.switchTab只能跳 tabBar 页面分包页面永远不能当 tabBar想跳回去得用navigateBack或reLaunch。同事第一次切分包把我的钱包塞进分包又设成 tabBar 页编译直接报错。踩坑记录分包后分享卡片打不开现象用户从微信分享卡片点进职位详情页面白屏控制台报page not found。排查过程navigateTo路径明明对本地开发也正常就线上分享进来打不开定位思路分享卡片跳的是旧链接/pages/job/detail?idxxx而职位详情页在分包重构时挪到了pages/job分包下路径变成了/pages/job/detail——老的分享链接失效了最终解决给职位详情做兼容路由在pages.json里加了一个空的pages/job/detail占位不更干净的做法是分享链接统一带分包前缀同时在主包留一个 redirect 页解析旧路径 302 到新地址。修完后把历史分享卡片全部检查了一遍确认都指向新路径。另外分包总大小也要盯单个分包超过 2MB或整包超限照样报错工具类、图片、公共组件尽量放common分包或static别每个分包都塞一份。体积治理分包也装不下时怎么办分包不是万能药。功能多了单个分包照样逼近 2MB。我们用的三板斧第一图片资源全走 CDN。本地static里只留启动必需的 logo 和占位图banner、图标、模板图全部用远程地址小程序包天然小一半。招聘海报那种动态生成图根本不落包走接口拿。第二公共逻辑收进 common 分包。多个分包都要用的工具函数、请求封装放pages/common各分包从那里 import别每个分包复制一份 utils。这也是preloadRule里预载它的原因——common 一到本地各分包开箱即用。第三低频组件按需注册。授权弹窗、分享面板这种组件别在app.vue里全局注册用到哪个页面再引哪个。全局注册看着省事每个分包都被迫带上一份组件代码。做完这三步主包从 3.6MB 降到 1.1MB构建报警彻底消失首屏白屏时间也短了——包体瘦了加载自然快。分包加载失败也别白屏分包有预加载但预加载不是百分百成功弱网下分包代码可能下载失败用户点进分包页面会白屏或卡在 loading。我们的兜底分包页面进入时包一层加载态 重试失败给用户明确提示而不是无限转圈// 分包页面 onLoad 里统一走这个守卫exportfunctionguardSubpackage(onReady){uni.showLoading({title:加载中...});setTimeout((){uni.hideLoading();onReadyonReady();},300);// 实际分包代码下载失败时onReady 里的接口会报错// 由页面级 catch 弹网络异常点击重试再走 onLoad 重新进入}还有个经验tabBar 页面永远放主包是硬规则但我的页面里的二级页设置、关于、意见反馈同样建议踢进分包——它们低频且独立塞主包纯属浪费。判断标准就一条这个页面用户每天必进吗不是就分包。preloadRule的network字段也要想清楚写all意味着用户用流量打开首页也预载分包包再小也是流量。我们的取舍是首页预载的pages/job、pages/common用all跳转频率高值得其余低频分包不配预载、用到再下。预载不是越多越好只预载点了必跳的那几个。可以直接抄走的清单主包只留高频tabBar 页 启动依赖其余全进分包。分包按业务域切一个功能域一个root如finance、integral、vip。预加载填好首页preloadRule预载高频分包network: all。跳转带 root 前缀navigateTo路径 分包 root 页面路径。switchTab 限主包分包页面不能设 tabBar跳转用navigateBack/reLaunch。分享链接要迁移分包重构后旧链接全失效留兼容路由或统一前缀。项目源码https://gitee.com/gzqkl/job-uniapp