发现问题
目前小程序分包大小有以下限制:
- 整个小程序所有分包大小不超过 20M
- 单个分包/主包大小不能超过 2M
分析问题
小程序官方:在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分。
在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示。
概括一下就是说,主包用来放首页及所有分包都会用到的公共资源。那么先来看下目前主包的依赖分析。
可以看到,我们的主包已经距离2MB很近了,common.js是最大的,因为其中有很多公共模块的js资源,如可回溯,埋点等;其次是app.wxss,放置公共的css,但是app.wxss居然有380KB。有点大的不太正常。
分析了一下:
- 全局引入的scss里面,有些并不真正意思上属于全局样式也放到公共样式里面了
- 打包后看到common.wxss里面的图片引入都是base64?并没有按照阈值去打包成base64还是cdn url引入形式,有些图片还50多k,怪不得wxss这么大
知道问题后下面就可以有的放矢了。
解决问题:减少小程序主包体积
非公共css放回各自组件
将一些非公共css放回组件本身,再看打包后依赖分析,可以看到,app.wxss从380KB->132KB,代码总体积明显降了,由原来的3.21MB->2.98M,主包也从1.93M->1.69M,主包足足减少了240KB,这对原本剩余可用体积本就不大的小程序来说犹如雪中送炭。
公共css及组件css中的图片引用路径进行url-loader处理
上面操作主包能减少200多KB主要因为有些图片其实并没有转化成cdn引用形式,都是base64格式,所以导致css非常大,那么需要优化css中图片的引入方式。
sass-loader
会解析~
,相当于@import语法一样,~相对于后面的路径,会告诉webpack去检索资源,loader 首先会尝试以相对路径解析 @import,如果它不能被解析,loader 将会尝试在 node_modules 中解析 @import。只在前面加上 ,那么/ 将会解析到用户的主目录(home directory)
基于原有配置:url-loader处理图片,设置图片转化阈值是1KB
// config/index.js
postcss: {
// ...
url: {
enable: true,
config: {
limit: 1024 // 设定转换尺寸上限
}
}
// ...
},
mini: {
publicPath: 'https://test.cdn.net/ias-web',
imageUrlLoaderOption: {
name: 'cdn/imgs/[contenthash:8]_[name].[ext]',
publicPath: process.env.NODE_ENV === 'development' ? '/' : 'https://test.cdn.net/ias-web'
}
},
解决思路:
由于原来css中使用相对路径引入图片,导致图片打包之后都是base64格式(小程序中是如此,h5会根据图片大小做处理),没有起到按指定图片大小生成base64格式或者cdn形式引入,所以这里首先需要让图片路径经过url-loader的处理。
- 将css里面图片引用的的资源有原来的相对路径替换成
~
开头(打包配置中已经定义了别名alias的@相对于项目主目录)
// 优化前
background: url(../../assets/images/header.png)
// 优化后
background: url(~@/assets/images/header.png)
本地通过build打包成生产包,可看到路径的变化,配置的图片路径转化阈值是1024(1KB)
// 优化前:实际超过1KB的图片的图片base64比以下大得多,这里为了方便展示删减了大小
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAOVBMVEUAAAC1tbW1tbX///+1tbW1tbXAwMC0tLS0tLS0tLS1tbW2tra1tbW3t7e1tbW1tbW1tbW2tra0tLQ5iBa1AAAAEnRSTlMAiUIC5tkK8sy/tXZTPCZrqGxEqinjAAAAuElEQVQoz4WT3Q6CMAxG267bQAT0vP/DKkYbIZB+F8uyk/W/EiqzjrX3Oupc5Kg2OSGf2p7eHara0tpiWsHvf7AoDCYhG0BL0AesO39lhcfvRekmB1lHv34h6O0WHD7+m7PGJ4jrim/xTwzlDJeB6X06Jnsc5r3ITJVzLJVZFL3AHzRiV9gYpbJc4YUqnbbly0Fb/o2e4MR4ElqSWFKWpKhJS64b+sRbMg7JMCWjmAxysgbZEiUr+ALtDw9fVVYh+wAAAABJRU5ErkJggg==)
// 小程序优化后打包:超过1KB的图片
background: url(https://test.cdn.net/ias-web/cdn/imgs/aa13wewe_header.png)
// 小程序优化后打包:没超过1KB的图片
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAOVBMVEUAAAC1tbW1tbX///+1tbW1tbXAwMC0tLS0tLS0tLS1tbW2tra1tbW3t7e1tbW1tbW1tbW2tra0tLQ5iBa1AAAAEnRSTlMAiUIC5tkK8sy/tXZTPCZrqGxEqinjAAAAuElEQVQoz4WT3Q6CMAxG267bQAT0vP/DKkYbIZB+F8uyk/W/EiqzjrX3Oupc5Kg2OSGf2p7eHara0tpiWsHvf7AoDCYhG0BL0AesO39lhcfvRekmB1lHv34h6O0WHD7+m7PGJ4jrim/xTwzlDJeB6X06Jnsc5r3ITJVzLJVZFL3AHzRiV9gYpbJc4YUqnbbly0Fb/o2e4MR4ElqSWFKWpKhJS64b+sRbMg7JMCWjmAxysgbZEiUr+ALtDw9fVVYh+wAAAABJRU5ErkJggg==)
小程序打包后可以看到没超过1KB图片生成base64,超过1KB的图片url会按照url-loader配置中的生成指定url(h5试了默认阈值是10KB,但也可以设置),图片会生成到dist/cdn/images/aa13wewe_header.png
,只要将图片推到远程cdn,再部署下小程序代码,看起来就大功告成了。
燃鹅......
进行本地调试:
// 优化前:实际超过1kb的图片的图片base64比以下大得多,这里为了方便展示删减了大小
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAOVBMVEUAAAC1tbW1tbX///+1tbW1tbXAwMC0tLS0tLS0tLS1tbW2tra1tbW3t7e1tbW1tbW1tbW2tra0tLQ5iBa1AAAAEnRSTlMAiUIC5tkK8sy/tXZTPCZrqGxEqinjAAAAuElEQVQoz4WT3Q6CMAxG267bQAT0vP/DKkYbIZB+F8uyk/W/EiqzjrX3Oupc5Kg2OSGf2p7eHara0tpiWsHvf7AoDCYhG0BL0AesO39lhcfvRekmB1lHv34h6O0WHD7+m7PGJ4jrim/xTwzlDJeB6X06Jnsc5r3ITJVzLJVZFL3AHzRiV9gYpbJc4YUqnbbly0Fb/o2e4MR4ElqSWFKWpKhJS64b+sRbMg7JMCWjmAxysgbZEiUr+ALtDw9fVVYh+wAAAABJRU5ErkJggg==)
// 小程序优化后本地调试:css中会提示do-not-use-local-path
background: url(/cdn/imgs/aa13wewe_header.png)
h5中在可以访问本地路径图片,但是小程序中并没有显示出图片,因为小程序的css不支持本地路径的图片引入。会报错提示:[渲染层网络层错误] app.wxss 中的本地资源图片无法通过 WXSS 获取,可以使用网络图片,或者 base64,或者使用<image/>标签。
由于h5和小程序有差异性,那么需要对小程序单独处理。这里的兼容处理就是在本地开发调试的时候默认都转成base64,方便本地进行开发。测试和线上部署则使用原有的配置。
// 修改配置
if (process.env.NODE_ENV === 'development') {
mergeConfig.mini.imageUrlLoaderOption.limit = 102400
}
这里修改url-loader转换base64的阈值,有两个用处:
- 兼容小程序本地调试
- 之前项目中没注意拿到的切图尺寸不对或者没经过压缩,导致图片太大,大于100KB,如果没有发现的话会造成资源过大请求缓慢,这里设置了阈值则在本地调试过程中如果有超多100KB的图片,在小程序中直接不会展示出来,也算是有效提醒,提前发现问题(如果图片实在超过100KB建议进行分段裁剪,分段引入),
温馨提示:本地小程序用二维码预览,如果本地代码新增了新的图片并且build打包后是cdn引用形式,需将代码部署到远端,部署cdn后,本地打包预览后请求的cdn图片才能显示出来。
结果
完成后,可以看到app.wxss从132KB->72KB,代码总体积从2.98MB-2.92MB,主包从1.69MB->1.63MB,减少60KB。
整个解决过程并没有想象中顺利,但还是有所收获。
总结
- 代码总体积由3.21MB->2.92M,主包也从1.93M->1.63M,主包足足减少了300KB
- 代码css中引用图片有相对路径改成
~@/assets/...
形式 - 本地调试小程序新增图片限制100KB,超过100KB本地调试不显示,引入图片尽量不要超过100KB
- 本地小程序用二维码预览,如果本地代码新增了新的图片并且build打包后是cdn引用形式,需将代码部署到远端,部署cdn后,本地打包预览后请求的cdn图片才能显示出来。