一.分包

1.为什么要分包呢?

因小程序有体积和资源加载限制,如果都放主包pages里面,一般项目肯定会超过2M,微信小程序的主包或者分包的大小是2M,总体积一共不能超过20M。

  • 主包:即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;
  • 分包:则是根据开发者的配置进行划分,也就是前边说的部分指定页面的代码。
  • 如果使用了分包: 在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,会把对应分包自动下载下来,下载完成后再进行展示。
  • 如果没有使用分包: 小程序启动时,会下载整个小程序代码包,等待整个包下载完成再去进行展示。

App默认为整包。从uni-app 2.7.12+ 开始,也兼容了小程序的分包配置。其目的不用于下载提速,而用于首页是vue时的启动提速。App下开启分包,除在pages.json中配置分包规则外,还需要在manifest中设置在app端开启分包设置

2.分包类型

分包有两种类型:普通分包和独立分包
普通分包: 依赖于主包,也可以引用主包内的文件,当小程序从普通的分包页面启动时,首先需要下载主包

独立分包: 小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。从独立分包中页面进入小程序时,不需要下载主包,可以很大程度上提升分包页面的启动速度。当用户进入普通分包或主包内页面时,主包才会被下载。

开发者可以按需将某些具有一定功能独立性的页面配置到独立分包中。
一般首页渲染页面可以放在独立分包中

使用独立分包时要注意:

  • 独立分包中不能依赖主包和其他分包中的内容,包括 js 文件、template、wxss、自定义组件、插件等(使用 分包异步化 时 js 文件、自定义组件、插件不受此条限制)

  • 主包中的 app.wxss 对独立分包无效,应避免在独立分包页面中使用 app.wxss 中的样式;

  • 独立分包中暂时不支持使用插件

  • 一个小程序中可以有多个独立分包

3.如何设置分包?

①需要在manifest.json中加入分包相关配置

小程序配置

我在项目中没有开启按需注入,因为我在分包中需要引入主包的组件,开启按需注入之后,分包引用的组件显示不出来

    /* 小程序特有相关 */
    "mp-weixin" : {
     // "lazyCodeLoading" : "requiredComponents",//按需注入
        "optimization":{"subPackages":true}, //开启分包
    },

APP配置

 "app-plus" : {
    /* APP 开启分包 每个分包单独编译成一个js文件(都包含在app内,不会联网下载),当App首页是vue时,可减小启动加载文件大小,提升启动速度。 */
        "optimization": {
            "subPackages": true
        },
 }
②在page.json中加入分包配置

root:分包根路径
pages:分包下页面的路径
name:分包别名,分包预下载时可以使用
independent: 分包是否是独立分包

	"subPackages": [{
		"root": "pagesA",
		"name":"pagesA",
		"pages": [{
			"path": "list/list", //path最前面不需要 斜杆 /
			"style": { ...}
		}],
		"independent":true//设置为独立分包
	}, {
		"root": "pagesB",
		"pages": [{
			"path": "detail/detail",
			"style": { ...}
		}]
	}],

打包原则

  • 声明 分包后,将按 分包配置路径进行打包,分包外的目录将被打包到主包中
  • subpackage 的根目录不能是另外一个 subpackage内的子目录
  • 分包和主包不能在同一目录下(比如:不能把分包放在pages下)
  • tabBar 页面必须在主包内

引用原则

  • packageA分包只能引用自己目录和主包下的文件 ,无法引用其它分包下的文件;使用 分包异步化 时不受此条限制

3.分包预加载配置preloadRule

开发者可以通过配置,在进入小程序某个页面时,由框架自动预下载可能需要的分包,提升进入后续分包页面时的启动速度。对于独立分包,也可以预下载主包。

分包预下载目前只支持通过配置方式使用,暂不支持通过调用 API 完成。

preloadRule 中,key 是页面路径,value 是进入此页面的预下载配置

packages:进入页面后预下载分包的 root 或 name。__ APP__ 表示主包。
network:在指定网络下预下载,可选值为:
all: 不限网络
wifi: 仅 wifi 下预下载


 "pages": ["pages/index"],
  "subpackages": [
    {
      "root": "important",
      "pages": ["index"],
    }
    ],
    //进入主包pagesx下的index页面时,加载分包important
 "preloadRule": {
    "pages/index": {
      "network": "all",
      "packages": ["important"]
    }
    }

二、按需注入和用时注入

通过以上的分包加载,我们可以让每个包独立加载,实现了包的按需加载,提升了小程序的启动时间。但是还有没有进一步提升启动时间的空间?
参考文档:按需注入和用时注入|微信开放文档

1、按需注入

小程序启动的过程中,除了代码包下载以外,代码注入也是一个主要的耗时环节,如果只是分包加载,还有以下问题:

  • 在小程序启动时,启动页面依赖的所有代码包(主包、分包、插件包、扩展库等)的所有 JS 代码会全部合并注入,包括包内其他未访问的页面。
  • 同时包内的所有页面和自定义组件的 JS 代码会被立刻执行。这造成很多没有使用的代码在小程序运行环境中注入执行,影响注入耗时和内存占用。

这时我们会想,如果只注入并执行当前页面和当前页面的自定义组件的代码。是不是会更好,于是有了按需注入。

自基础库版本 2.11.1 起,小程序支持通过配置,有选择地注入必要的代码,以降低小程序的启动时间和运行时内存。

//app.json配置
{
  "lazyCodeLoading": "requiredComponents"
}

注意事项

我在项目中没有开启按需注入,因为我在分包中需要引入主包的组件,开启按需注入之后,分包引用的组件显示不出来

  • 启用按需注入后,小程序仅注入当前访问页面所需的自定义组件和页面代码。未访问的页面、当前页面未声明的自定义组件不会被加载和初始化,对应代码文件将不被执行。请开发者修改配置后务必确认小程序的表现正常。
  • 启用按需注入后,页面 JSON 配置中定义的所有组件和 app.json 中 usingComponents配置的全局自定义组件,都会被视为页面的依赖并进行注入和加载。建议开发者及时移除 JSON中未使用自定义组件的声明,并尽量避免在全局声明使用率低的自定义组件,否则可能会影响按需注入的效果。
  • 插件包和扩展库目前暂不支持按需注入。如果需要实现插件按需加载,可以考虑将插件置于一个分包,并通过「分包异步化」的形式异步引入。 启用

2、用时注入

用时注入使当前页面渲染前只注入并执行当前页面相关的非自定义组件的代码文件,用占位组件(例如简单的view组件)替换自定义组件在页面的位置,进一步提升了小程序启动速度,在当前页开始渲染时,再注入自定义组件并换回占位组件

在已经指定 lazyCodeLoading 为 requiredComponents 的情况下,为自定义组件配置 占位组件,组件就会自动被视为「用时注入」组件:

  1. 每个页面内,第一次渲染该组件前,该组件都不会被注入;
  2. 每个页面内,第一次渲染该组件时,该组件会被渲染为其对应的占位组件,渲染流程结束后开始注入;
  3. 注入结束后,占位组件被替换回对应组件。

三、总结

区别:

  • 分包加载是按需求加载不同功能模块的代码包,节省了非必要代码包的下载时间;
  • 按需注入是在已经加载代码包后按照需求注入和执行当前需要的代码文件,节省了非相关页面代码文件的注入执行时间。

优缺点:

  • 按需注入可以在分包加载的基础上进一步提升小程序启动时间;但是对代码文件依赖管理的要求比较高,如果有些全局方法和属性不是在当前页面引用的代码文件中声明赋值的,则在当前页面无法正常调用,增加了逻辑复杂性。

配置选择:按照需求选择,如果分包加载已经能够满足我们的需求,则不必为了追求极致而使用按需注入。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐