告别加载延迟:优化微信小程序主包的终极指南小程序主包超2M问题解决方案 在开发小程序时,你是否遇到过主包超过2M的困境?
小程序主包超2M问题解决方案
在开发小程序时,你是否遇到过主包超过2M的困境?这不仅影响加载速度,还可能阻碍业务的进一步发展。以下是一些导致主包过大的原因,以及相应的技术解决方案。
原因分析
- 通用组件滥用:习惯性地将所有组件放在全局
components
目录下,导致即使只在分包中使用的组件也被打包进主包。 - 全局注册组件:一些只在分包中使用的组件,由于全局注册,也被打包进了主包。
- 静态资源处理不当:未合理管理静态资源,如图片、字体等。
- 第三方UI全局引入:在
pages.json
中全局引入了第三方UI组件,即使分包中未使用,也被打包进主包。 - 第三方node包:使用第三方node包时,这些包也被打包进了主包。
技术解决方案
为了解决上述问题,我们可以采取以下措施:
- 分包内复制组件:将
components
、第三方UI和node包复制到分包内,并按分包路径引用,以减轻主包负担,让分包分担。 - 手动处理静态资源:对静态资源进行优化。
实施步骤
- 复制项目目录:首先,将项目目录复制到指定位置。
- 复制全局组件:将全局组件(如
components
、uView
、node包等)复制到分包中。 - 处理组件信息:对复制的组件进行文件类型分类,设置主包和分包的引用路径。
- 修改分包文件:检查分包中的文件,确保使用全局组件时,引用路径指向分包。
- 修改主包文件:同样,检查主包中的文件,确保正确引用全局组件。
- 修改全局组件文件:确保全局组件文件中的引用路径指向正确的位置。
- 删除
pages.json
中的全局组件引用:清理pages.json
中的不必要全局组件引用。
代码实现
以下是实现上述解决方案的代码示例:具体源码链接在这里《源码链接》请点这里
定义接口入参
const dir = 'wx-dist'
main({
dirFileName: dir, // 目标目录名称
sourceDir: path.join(__dirname, '../'), // 根目录路劲
copyFileSourceDir: path.join(__dirname, `../unpackage/${dir}`), // 当前项目重新复制一份到目标目录路劲
excludeFiles: [ // 不需要复制得文件,仅支持根目录
'unpackage',
// 具体下载我提供的 示例项目,上面的代码我已经处理好了
...
],
mainPackages: [// 主包文件夹
{ path: 'pages/index' },
{ path: 'pages/exception' },
],
subPackages: [// 分包文件夹
{ path: 'pages/login' },
{ path: 'pages/common' },
{ path: 'pages-room-tickets-manage' },
{ path: 'pages-report' },
...
],
/**
* 全局组件
* sourcePrefix 全局组件引用路劲前缀
* sourceDir 组件源目录
* copyFileDir 复制到目标目录
* prefix 全局引用组件使用的前缀 <t-xxx></t-xxx> <myp-xxxx></myp-xxxx>
* easyComcustomPath pages.json 文件全局自定义根目录,如果为真,默认该目录下得组件为全局引入的组件(会自动加入 improt xxx from xxxx),否则当作普通组件处理(只替换路劲)注意不带 @ 符号
*/
components: [
{ sourcePrefix: '@/mypUI', sourceDir: 'mypUI', copyFileDir: 'mypUI', prefix: 'myp-', easyComcustomPath: 'mypUI' },
{ sourcePrefix: '@/uview-ui', sourceDir: 'uview-ui', copyFileDir: 'uview-ui', prefix: 'u-', easyComcustomPath: 'uview-ui/components' },
{ sourcePrefix: '@/components', sourceDir: 'components', copyFileDir: 'tComponents', prefix: 't-', easyComcustomPath: 'components/common' },
{ sourcePrefix: 'ch-xxxx-element', sourceDir: 'node_modules/ch-xxxx-element', copyFileDir: 'ch-xxxx-element', prefix: '', easyComcustomPath: '' },
],
/**
* 自定义替换文件内容
* sourceDir 替换文件目标
* replace 替换内容
* value 替换后的内容
*/
replaceList: [
{ sourceDir: 'pages.json', replace: '"myp-(.*)": "@/mypUI/myp-$1/myp-$1.vue",', value: '' },
{ sourceDir: 'pages.json', replace: '"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue",', value: '' },
{ sourceDir: 'pages.json', replace: '"^t-(.*)": "@/components/common/$1.vue"', value: '' },
]
})
入口文件逻辑
module.exports = main => {
const { sourceDir, copyFileSourceDir, excludeFiles, mainPackages, subPackages, components, replaceList } = main;
/**
* 1,删除历史目录
* 2,把项目复制一份进来
* 3,把全局组件复制一份到项目得分包中
*/
copyFile(main)
/**
* 对复制的组件进行文件类型分类,设置主包和分包的引用路径。
* 1,获取全局组件js,css,vue,nvue文件等相关信息 返回类型 new Map()
* componentsRows.get('vue')
* componentsRows.get('js')
* componentsRows.get('css')
* componentsRows.get('nvue')
* componentsRows.get('...')
*
* mainPackagesPath, // 主包引用的路径 包含 '@' 符号 @/components/xxx.vue
* subPackagesPath, // 分包引用的路径 tComponents/xxx.vue
* verifyPath, // 验证路径 用于判断当前页面是否引用过该组件 ch-xxxx-element/index
* fileType, // 文件类型 vue,nvue,css,js,json...
* humpRows, // 文件匹配的类型 以及 命名规则
*/
const componentsRows = onComponents(main)
/**
* 修改分包文件:检查分包中的文件,确保使用全局组件时,引用路径指向分包。
* 修改主包文件:检查主包中的文件,确保使用全局组件时,引用路径指向主包也就是 @/ 。
* 修改全局组件文件:检查主包中的文件,确保使用全局组件时,引用路径指向主包也就是 @/
*/
page(main, componentsRows)
/**
* 替换字符串
*/
replaceStrFile({
targetPath: copyFileSourceDir,
replaceList: replaceList
})
}
处理页面时的注意事项
在团队开发中,由于代码风格的差异,字符串替换处理可能会遇到一些挑战。以下是一些在处理页面时需要注意的事项,以确保路径替换的准确性和一致性。
文件命名和引用
一些团队成员可能会将文件命名为“业务名称”,而实际文件名为index
。在页面中,通常我们会这样引用:
// 正常的引用
import xxx from 'xxxx/xxx/index.vue';
// 或者
import xxx from 'xxxx/xxx/index';
然而,有些团队成员可能直接引用“业务名称”,忽略了index
,这会导致路径替换失败。为了解决这个问题,需要确保所有引用路径都补全index
。
import xxx from 'xxxx/xxx';
优化前后对比:小程序主包大小显著减少
在进行代码优化之前,我们的小程序主包大小已经达到了2.04M,这不仅影响了加载速度,也限制了进一步的功能开发。经过一系列的代码优化措施,我们成功地将主包大小缩小到了1.57M。以下是优化前后的对比效果:
优化前
主包大小: 2.04M
优化后
主包大小: 1.57M
总结
通过这次优化,我们不仅显著减少了小程序主包的大小,还提高了应用的加载速度和用户体验。现在,团队可以更加自由地开发新功能,而不必担心主包大小超标的问题。这次成功的优化证明了代码优化的重要性,也为未来的开发工作提供了宝贵的经验。
转载自:https://juejin.cn/post/7414732427300454434