4、包体积优化:代码分包策略、图片资源压缩、无用代码移除
抖音小程序的包体积,说白了就是你的「入场券」。
我记得刚做小程序那会儿,团队吭哧吭哧写了一个月,结果上传代码时提示「主包超过2MB」。当时整个人都懵了。后来我才明白,包体积优化不是锦上添花,而是生死线。今天咱们就聊聊怎么把这体积降下来。
4.1 代码分包策略:别把所有鸡蛋放一个篮子里
抖音小程序有个硬性规定:主包不能超过2MB,整个小程序不能超过20MB。你想想看,一个页面带点图片、带点组件,分分钟就超了。
我个人的习惯是:先拆再写。不是等代码写完了再想怎么拆,而是项目初始化时就规划好分包结构。
4.1.1 分包的基本规则
分包的核心思路很简单:把不常用的页面扔到分包里。比如用户设置、帮助中心、活动页这些,用户不会一进来就点。
// app.json 分包配置示例
{
"pages": [
"pages/index/index",
"pages/home/home"
],
"subPackages": [
{
"root": "packageA",
"pages": [
"pages/setting/setting",
"pages/help/help"
]
},
{
"root": "packageB",
"pages": [
"pages/activity/activity",
"pages/coupon/coupon"
]
}
]
}
4.1.2 独立分包:让用户少等几秒
独立分包是个好东西。它不依赖主包,可以单独加载。我在做电商小程序时,把「秒杀页面」做成了独立分包。用户从分享链接点进来,直接加载秒杀页,不用等主包加载完。
{
"subPackages": [
{
"root": "packageFlash",
"pages": [
"pages/flash/flash"
],
"independent": true // 独立分包
}
]
}
4.1.3 预加载分包:提前加载,体验丝滑
用户从A页面跳到B页面,如果B在分包里,加载会有延迟。怎么办?预加载。
{
"preloadRule": {
"pages/index/index": {
"network": "all",
"packages": ["packageA"]
}
}
}
这样用户在首页时,系统已经在后台悄悄加载packageA了。等用户点击跳转,瞬间打开。
4.2 图片资源压缩:一张图省出100KB
小程序里最占体积的,往往不是代码,而是图片。我见过一个项目,光图片就占了1.5MB,代码才500KB。
4.2.1 图片格式怎么选
| 格式 | 适用场景 | 压缩率 |
|---|---|---|
| JPEG | 照片、渐变图 | 高 |
| PNG | 图标、透明图 | 中 |
| WebP | 通用(推荐) | 极高 |
| SVG | 简单图标 | 极小 |
我个人强烈推荐WebP。同样的图片,WebP比PNG小30%-50%。抖音小程序原生支持WebP,放心用。
4.2.2 压缩工具怎么选
我常用的工具就两个:
- TinyPNG:在线压缩,支持PNG和WebP。拖进去就行,傻瓜式操作。
- ImageOptim:Mac端工具,批量压缩,能去掉图片里的EXIF信息(那些拍摄参数、GPS坐标,小程序里根本用不上)。
避坑指南:我曾经把一张1920x1080的图片直接放进了小程序。后来发现,手机屏幕才375x667,加载那么大图干嘛?先缩放到实际显示尺寸的2倍(适配Retina屏),再压缩。一张图从500KB变成了30KB。
4.2.3 图片放在哪里
能放CDN就别放本地。本地图片会打进包体里,CDN图片只占一个URL。
// 错误做法:本地图片
<image src="/images/banner.png" />
// 正确做法:CDN图片
<image src="https://cdn.example.com/banner.png" />
但注意:首屏的关键图片(比如首页Banner)建议放本地。因为CDN加载有网络延迟,首屏体验更重要。非首屏的图片,全扔CDN。
4.3 无用代码移除:别让死代码占地方
项目做久了,代码里难免有「僵尸代码」——写了但没用的函数、注释掉的代码块、重复的工具方法。这些代码不会报错,但会白白增加包体积。
4.3.1 手动清理:最笨但最有效
我每两个月会做一次「代码大扫除」。打开项目,搜索以下关键词:
// TODO—— 看看是不是忘了删console.log—— 调试完记得删掉function unused—— 没被调用的函数
嗯,这里要注意:别用全局搜索「删除」。我建议用VS Code的「引用查找」功能,右键点击函数名,看看有没有被调用。没被调用的,删。
4.3.2 工具辅助:让机器帮你找
手动清理太累,我推荐用工具:
- ESLint + no-unused-vars:自动检测未使用的变量和函数。
- Webpack Bundle Analyzer:可视化分析包体积,一眼看出哪个模块最大。
// 安装依赖
npm install --save-dev webpack-bundle-analyzer
// 在构建配置中启用
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
};
运行后浏览器会打开一个交互式图表。你一看就知道:哦,原来这个组件占了200KB,那个库占了500KB。然后决定要不要替换。
4.3.3 Tree Shaking:自动摇掉死代码
Tree Shaking是Webpack自带的功能。它会把「只导入但没使用」的代码自动移除。
// 错误导入:整个库都打包进来了
import _ from 'lodash';
// 正确导入:只打包用到的函数
import { debounce } from 'lodash';
但注意:Tree Shaking只对ES Module有效。如果你用CommonJS(require),它摇不动。所以写代码时尽量用import和export。
4.4 实战:一个优化案例
我接手过一个项目,包体积从3.2MB优化到了1.1MB。怎么做的?
- 分包:把「个人中心」「订单列表」「帮助中心」拆到分包里,主包从2.1MB降到1.3MB。
- 图片压缩:所有PNG转WebP,缩放到实际尺寸,从800KB降到200KB。
- 移除无用代码:删掉了3个没用的工具函数、2个废弃的页面、一堆console.log,省了150KB。
- 替换第三方库:把moment.js换成day.js,省了300KB。
你看,其实没什么高深的技术。就是该拆的拆、该压的压、该删的删。但很多人就是懒得做。
最后说一句:包体积优化不是一次性工作。每次发版前,都看一眼包体积。养成习惯,你会发现——原来2MB的包,也能装下这么多东西。