uni-app 系列(六):性能优化、分包与多端发布
2026年8月6日 · 17 分钟
一、分包:小程序体积的救命稻草
微信小程序主包有 2MB 上限(总包 20MB,需分包)。项目一大,主包必爆。分包就是把部分页面拆成独立的包,按需下载。
// pages.json
{
"pages": [ /* 主包页面:tabBar 页、首页等高频页 */ ],
"subPackages": [
{
"root": "pkg-order", // 分包目录
"pages": [
{ "path": "list/list" },
{ "path": "detail/detail" }
]
}
],
"preloadRule": {
// 进入首页时预下载订单分包,兼顾体积与体验
"pages/index/index": { "packages": ["pkg-order"] }
}
}
原则:主包只放 tabBar 页和最高频的启动路径页面;低频模块(如订单、设置、活动页)拆进分包;用 preloadRule 分包预下载抵消首次进入分包的延迟。
二、启动与运行性能优化清单
启动优化
- 减小主包体积:分包 + 图片走 CDN,不塞进包里;
static只放必需资源。 - 首页轻量化:首屏请求精简、骨架屏占位、非首屏数据懒加载。
- 按需引入:easycom 已做到组件按需;第三方库避免整包引入。
长列表优化(高频考点)
- 触底分页(
onReachBottom)而非一次性加载全部。 - 虚拟列表:超长列表只渲染可视区,用
recycle-list或社区虚拟列表组件;App 端可用nvue的 list。 - 图片懒加载:
<image lazy-load>。 - 避免频繁 setData/大数据 diff:小程序
setData数据量大、频率高会卡,分批更新、只更新变化字段。
渲染优化
- 减少逻辑层↔视图层通信(必要时用
renderjs)。 - 长列表/复杂动画页面上
nvue。 - 合理用
v-ifvsv-show:频繁切换用v-show,一次性用v-if。
三、setData 为什么是小程序性能的关键
小程序双线程架构下,逻辑层的数据要序列化传输到视图层渲染,这个动作就是 setData(uni-app 里 this.data 赋值/响应式更新底层就是它)。数据越大、越频繁,通信开销越大,是卡顿主因。优化:① 只传变化的字段,别整个大对象 setData;② 合并高频 setData;③ 列表数据分页而非全量。
四、各端发布流程
H5
npm run build:h5
# 产物 dist/build/h5 → 部署到任意静态服务器 / CDN,配好 base 路径
微信小程序
npm run build:mp-weixin
# 产物 dist/build/mp-weixin → 微信开发者工具打开 → 上传代码 → 提交审核 → 发布
App(iOS / Android)
用 HBuilderX:发行 → 原生 App 云打包(或本地打包),生成 apk/ipa。iOS 需 Apple 开发者账号与证书,上架 App Store 审核;Android 打 apk/aab 上各应用市场。
五、上线合规要点(国内)
- 小程序类目资质:不同业务(电商、社交、二手)需对应类目和资质,提审前先查平台规范。
- 内容安全:有 UGC(用户发内容)必须接内容审核(文本/图片),否则违规下架。
- 隐私合规:遵循个人信息保护法,配置隐私协议、权限用途说明;微信需填"用户隐私保护指引"。
- iOS 审核:有第三方登录须提供 Apple 登录;避免热更新违规(App 端动态更新有边界)。
- 备案:H5/服务端域名需 ICP 备案,小程序服务器域名要在后台配置白名单。
六、条件编译在工程化里的实战
发布多端时,条件编译不止用于业务逻辑,也用于配置差异:
// 不同端不同的 API 基址、appid、埋点开关
// #ifdef MP-WEIXIN
const CONFIG = { base: "https://wx.api.com" };
// #endif
// #ifdef H5
const CONFIG = { base: "https://h5.api.com" };
// #endif
七、本阶段必须掌握的知识点
- 分包:主包 2MB 上限、
subPackages配置、preloadRule预下载;主包只放高频页。 - 启动优化:减小主包、首页轻量、按需引入。
- 长列表优化:触底分页、虚拟列表、图片懒加载、控制 setData。
- setData 是小程序性能关键——双线程序列化通信,少传、合并、分页。
- 各端发布流程(H5 静态部署 / 小程序上传审核 / App 云打包上架)。
- 国内上线合规:类目资质、内容审核、隐私、iOS 审核、备案。
八、高频面试题
Q1:小程序主包超过 2MB 上传失败,怎么解决?
A:用分包。在 pages.json 配 subPackages,把低频模块(订单、设置、活动等)的页面拆到独立分包目录,主包只保留 tabBar 页和启动路径上的高频页面。这样主包控制在 2MB 内,分包在用户进入对应模块时按需下载。再用 preloadRule 配置分包预下载(如进首页时后台预载订单分包),抵消首次进入分包的等待。此外把大图片放 CDN、避免把资源打进包,也能显著减小体积。
追问:分包后首次进入分包会不会有明显等待?怎么优化?
A:会有一次分包下载耗时。优化手段是 preloadRule——在用户大概率会去的入口页(如首页)配置预下载目标分包,让下载在用户真正点进去之前就后台完成;同时分包内也做首屏骨架屏,进一步弱化感知。
Q2:uni-app / 小程序长列表卡顿,如何优化?
A:多管齐下:① 分页加载,用 onReachBottom 触底加载下一页,不一次性渲染全部;② 虚拟列表,只渲染可视区节点(recycle-list 或社区虚拟列表组件,App 端可用 nvue list);③ 图片懒加载 lazy-load;④ 控制 setData——只更新变化字段、合并高频更新、避免一次 setData 巨大数组;⑤ 复杂列表页考虑用 nvue 原生渲染。
追问:为什么频繁 setData 会导致卡顿?
A:小程序是双线程架构,逻辑层与视图层隔离,数据更新要序列化后跨线程传给视图层再渲染。setData 的数据量越大、调用越频繁,序列化和通信、以及视图层 diff 的开销越大,主线程被占用就卡。所以要少传(只传 diff 字段)、少调(合并更新)、分页(减小单次数据量)。
Q3:uni-app 各端是怎么发布的?
A:H5 build:h5 出静态产物,部署到静态服务器/CDN;小程序 build:mp-weixin 出产物,用微信开发者工具上传代码、提交审核、发布;App 用 HBuilderX 云打包或本地打包生成 apk/ipa,Android 上应用市场、iOS 走 App Store 审核(需开发者账号与证书)。不同端产物不同,但都是同一套源码按目标编译而来。
追问:App 端能像 H5 一样随时热更新吗?
A:uni-app 的 App 支持资源热更新(wgt 包,更新 JS/样式/页面等资源),可绕过应用市场审核快速修 bug。但有边界:涉及原生模块变更、或触碰各应用商店(尤其 iOS)审核红线的更新不能走热更新,否则可能被下架。合规做法是热更新只用于资源级修复,重大更新仍走正常发版。
Q4:条件编译除了写业务逻辑,还能用在发布/工程化的哪些地方?
A:可用于多端配置差异——不同端的 API 基址、各平台 appid、埋点/统计 SDK 开关、甚至 manifest.json/pages.json 的平台差异项,都能用条件编译区分,保证每个端的产物只包含自己需要的配置与代码,既安全又减小体积。