likes
comments
collection
share

告别加载延迟:优化微信小程序主包的终极指南小程序主包超2M问题解决方案 在开发小程序时,你是否遇到过主包超过2M的困境?

作者站长头像
站长
· 阅读数 104

小程序主包超2M问题解决方案

在开发小程序时,你是否遇到过主包超过2M的困境?这不仅影响加载速度,还可能阻碍业务的进一步发展。以下是一些导致主包过大的原因,以及相应的技术解决方案。

原因分析

  1. 通用组件滥用:习惯性地将所有组件放在全局 components 目录下,导致即使只在分包中使用的组件也被打包进主包。
  2. 全局注册组件:一些只在分包中使用的组件,由于全局注册,也被打包进了主包。
  3. 静态资源处理不当:未合理管理静态资源,如图片、字体等。
  4. 第三方UI全局引入:在 pages.json 中全局引入了第三方UI组件,即使分包中未使用,也被打包进主包。
  5. 第三方node包:使用第三方node包时,这些包也被打包进了主包。

技术解决方案

为了解决上述问题,我们可以采取以下措施:

  1. 分包内复制组件:将 components、第三方UI和node包复制到分包内,并按分包路径引用,以减轻主包负担,让分包分担。
  2. 手动处理静态资源:对静态资源进行优化。

实施步骤

  1. 复制项目目录:首先,将项目目录复制到指定位置。
  2. 复制全局组件:将全局组件(如 componentsuView、node包等)复制到分包中。
  3. 处理组件信息:对复制的组件进行文件类型分类,设置主包和分包的引用路径。
  4. 修改分包文件:检查分包中的文件,确保使用全局组件时,引用路径指向分包。
  5. 修改主包文件:同样,检查主包中的文件,确保正确引用全局组件。
  6. 修改全局组件文件:确保全局组件文件中的引用路径指向正确的位置。
  7. 删除 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

告别加载延迟:优化微信小程序主包的终极指南小程序主包超2M问题解决方案 在开发小程序时,你是否遇到过主包超过2M的困境?

优化后

主包大小: 1.57M

告别加载延迟:优化微信小程序主包的终极指南小程序主包超2M问题解决方案 在开发小程序时,你是否遇到过主包超过2M的困境?

总结

通过这次优化,我们不仅显著减少了小程序主包的大小,还提高了应用的加载速度和用户体验。现在,团队可以更加自由地开发新功能,而不必担心主包大小超标的问题。这次成功的优化证明了代码优化的重要性,也为未来的开发工作提供了宝贵的经验。


《源码链接》请点这里

转载自:https://juejin.cn/post/7414732427300454434
评论
请登录