赞
踩
小程序官方文档:
分包加载 | 微信开放文档developers.weixin.qq.com/miniprogram/dev/framework/subpackages.html
uniapp 分包文档:
uni-app官网uniapp.dcloud.io/collocation/pages?id=subpackages
原文地址:
uniapp分包(详尽版)copyfuture.com/blogs-details/20201128151522074lqjqh6asz92cv6c编辑
PS:本文是笔者对基于uniapp的一小程序项目进行分包后的复盘文档,不足之处请多多指教。
1). 主包:本项目中初始化时所必须的页面。
项目在启动时,将从主包进入,分包在用户未进入时不会加载,只有在进入分包模块时才会加载。
tabbar页面以及模块间共有的页面,如果该项目有账号限制(即非注册账号不可进入主界面),也应将登录页放置在主包内
2). 分包:除主包外的所有页面都应放置在分包内,为避免读者混淆,本文会将该分包定义为子包
优化项目首次启动的下载时间;小程序默认就是整包(主包)下载,但这会导致整个项目只有在全部加载完毕后才会回显到用户眼前,这样虽然可以使用加载动画进行优化,但也会有部分可能导致用户流失;
防止项目超出小程序官方对小程序项目打包后的大小限制;
若不分包,整个程序最大限制不能超过2M,分包后,整个项目(包含主包+子包)最大不能超过16M,单个包不能超过2M (这样就规避了项目最大不得超过2m的限制)
PS: 由于笔者仅做了微信小程序分包,因而以下也仅对面向微信小程序的uniapp项目有效
PS: 笔者是tabbar页作为单模块划分子包,即每个tabbar均作为一个子包模块
添加相关字段
- // "mp-weixin"
- "optimization":{
- "subPackages":true //是否启用分包优化
- }
原则:pages内只允许存放tabbar页面路由,以及各个子包所共有的页面页面,如果有登录页且不登录无法进入主页面,该登录页面路由也应放置在pages路由内
定义:单个模块内的除主包内文件的所有的文件,
比如: 假设一个tabbar模块内原本有index(tabbar页).vue,notice.vue,about.vue这三个页面,将index.vue这个页面路由放置pages.json中的pages数组内,对应的将index.vue放置在项目中的pages目录内
假设notice.vue与about.vue没有在别的tabbar模块中被使用,则应该将notice.vue和about.vue两个页面文件放置在subPackages中
若notice.vue与about.vue这两个页面中有被别的模块使用,则同样应该将其放置在pages主包内,为防止其与其他tabbar页面混淆,应该在pages目录内再单独开辟一个目录专门用于存放共有页
弄懂了以上原则,接下来便可以实践一下了
(pages.json)内新增subPackages字段,与pages同级,同样是数组格式,期内每一个对象均对应tabbar内的每一个模块,
(项目目录)每一个对象都应在项目中生成每一个目录,这个目录与pages目录同级
- //pages.json
- "pages":[
- //这里仅存放tabbar,以及公共页
- ],
- "subPackages":[
- //subPackages数组里的每一个对象都代表了对应tabbar模块里的除tabbar中index.vue以外所有的页面,且该数组里每一个对象都在项目目录中与pages目录平级
- //举个栗子 这里是首页模块,index.vue由于是tabbar页面,故而被放置在了pages.json中,剩余两个文件并没有被其他tabbar模块使用,因而被放置在了这里
- {
- "root":"pages_Index", //这里代表根目录的映射,表示在项目中这个模块的根目录也就是上面说的与pages目录平级的目录名
- "pages":[ // 这里的pages表示分包内的页面,凡在该子包的pages目录下,均不可被其他子包模块访问
- //这里指的是原本从pages页中迁移来的,仅本模块专属的页面,其格式规范遵循tabbar所在pages数组规范
- {
- // 网上有人说path路径必须由pages_Index根目录开始,但是在实践过程中发现不从根目录开始也可以,原因猜测是root本身已定义了根目录
- // 原目录为: /pages_index/packet/notice
- path":"packet/notice",
- "style": {
- "navigationBarTitleText": "我是子包文件"
- }
- },
- ]
- }
- ]
目录结构如下:
pages.json如下:
这样便完成了配置的第二步
笔者之前一直强调的分包越早越好的原因就在于此,一但项目到了微信2m限制,则会直接导致项目无法在开发者工具中运行,虽然分包可以在整个项目周期任一进度进行,但是需花费的时间是与项目进度是成正比的,即项目进度越到尾期,则分包需要花费的时间也就越长,笔者对此深有体会 (流眼泪.jpg)
如果在项目中末期才进行分包,此时需要开发者站在整个项目角度上,对每个模块,每个页面,每个网络请求都要了然于胸,可以借助于思维导图工具,将项目所有模块所有页面都列出来,剔除tabbar页面和模块间共有页面,然后将剩余页面填充至指定子包目录下,并在subPackages目录下声明该页面路径, 并且,开发者必须要重新定义路由跳转路径以及组件引入方式,这一点极为繁琐,且极易出错造成损失,因而建议开发者在走这一步前预先做好备份。
导入组件路径建议直接更换成以@开头的绝对路径来替换省略号开头的相对路径,防止以后可能再次发生的变更
跳转路由也应换成绝对路径,(路由更换后跳转失败? 请点击这里)
在本过程中,可能会出现各种引用错误或者无法跳转的问题,此时需要开发者心态平缓,并一定要谨慎检查
如果在开发者工具中运行整个项目显示没有报错信息,则可以在真机调试,如果有短时弹框 “ 加载模块中 ”,则表示分包成功
那么问题来了:我不想用户看到这几个丑陋的字,该怎么做?
出现这几个字的原因是由于用户刚进入的界面必定是主包,而在用户进入分包的时候,由于分包资源还未下载,所以微信官方便贴心的提示用户正在加载分包资源
笔者:微信我谢谢你呀!(超大声哔哔)
那么接下来要说的,就是关于这类问题的解决办法: 分包预加载
定义:在用户进入某个页面时,同时静默下载跟该页面有关的子包文件
与subPackages平级添加preloadRule对象,
该对象内部的key指的是某个页面路径,也就是当用户进入某个页面时,需要预加载的页面路径,
value
- //pages.json
- //以子包pages_index为例
- "subPackages":[
- //分包模块
- {
- "root" : "pages_index",
- "pages" : [
- {
- "path" : "packet/notice",
- "style" : { "navigationBarTitleText": "我是子包页面"}
- }
- ]
- }
- ],
- "preloadRule" :{
- "pages/index/index":{ //要进行预加载时用户要进入的页面路径
- "network":"all", // 什么网络下支持允许预加载,默认wifi: wifi/all
- "packages":["pages_Index"] // 要进行预加载的子包名
- },
- }
使用分包预加载功能,
如果配置成功,开发者console控制台会输出以下信息:
分享一个自己的初始化配置表:
分包目录: pagesA /pagesB/pagesC/pagesD, 使用的时候把这几个名字改成符合自己项目的命名吧.
- {
- "easycom": {
- "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
- },
- "pages": [
- {
- "path": "pages/index/index"
- },
- {
- "path": "pages/user/user",
- "style": {
- "navigationBarTitleText": "我的",
- "enablePullDownRefresh": false
- }
- }
- ,{
- "path" : "pages/i18n/i18n",
- "style" :
- {
- "navigationBarTitleText": "",
- "enablePullDownRefresh": false
- }
-
- }
- ,{
- "path" : "pages/test/test",
- "style" :
- {
- "navigationBarTitleText": "",
- "enablePullDownRefresh": false
- }
-
- }
- ,{
- "path" : "pages/result/result",
- "style" :
- {
- "navigationBarTitleText": "",
- "enablePullDownRefresh": false
- }
-
- }
- ],
- "subPackages": [{
- "root": "pagesA",
- "pages": [{
- "path": "test/test",
- "style" :
- {
- "navigationBarTitleText": "pagesA",
- "enablePullDownRefresh": false
- }
- }
- ]
- }, {
- "root": "pagesB",
- "pages": [{
- "path": "test/test",
- "style" :
- {
- "navigationBarTitleText": "pagesB",
- "enablePullDownRefresh": false
- }
- }
- ]
- },{
- "root": "pagesC",
- "pages": [{
- "path": "test/test",
- "style" :
- {
- "navigationBarTitleText": "pagesC",
- "enablePullDownRefresh": false
- }
- }
- ]
- },{
- "root": "pagesD",
- "pages": [{
- "path": "test/test",
- "style" :
- {
- "navigationBarTitleText": "pagesD",
- "enablePullDownRefresh": false
- }
- }
- ]
- }],
- "globalStyle": {
- "navigationBarTextStyle": "black",
- "navigationBarTitleText": "",
- "navigationBarBackgroundColor": "#F8F8F8",
- "backgroundColor": "#F8F8F8",
- },
- "tabBar": {
- "color": "#7A7E83",
- "selectedColor": "#e97516",
- "borderStyle": "white",
- "backgroundColor": "#fff",
- "list": [{
- "pagePath": "pages/index/index",
- "iconPath": "static/tabbar/home.png",
- "selectedIconPath": "static/tabbar/home-active.png",
- "text": "首页"
- },
- {
- "pagePath": "pages/user/user",
- "iconPath": "static/tabbar/user.png",
- "selectedIconPath": "static/tabbar/user-active.png",
- "text": "个人中心"
- }
- ]
- },
- "permission": {
- /* 小程序在这里设置定位没效果,必须在manifest.json中设置 */
- // "scope.userLocation": {
- // "desc": "获取用户当前位置"
- // }
- }
- }
补充说明:
所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据pages.json的配置进行划分。
在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,会把对应分包自动下载下来,下载完成后再进行展示。此时终端界面会有等待提示。
App默认为整包。从uni-app 2.7.12+ 开始,也兼容了小程序的分包配置。其目的不用于下载提速,而用于首页是vue时的启动提速。App下开启分包,除在pages.json中配置分包规则外,还需要在manifest中设置在app端开启分包设置,详见:https://uniapp.dcloud.io/collocation/manifest?id=app-vue-optimization
上面文档出处:
pages.json 页面路由 | uni-app官网uniapp.dcloud.net.cn/collocation/pages.html#subpackages编辑
分包后,小程序项目由 1 个主包 + 多个分包组成:
主包里的资源(js, template, wxss, components, 图片)都是全局的,可以被公用;而每个分包相当于有自己的“作用域”,自己的资源,只能用自己的或者使用主包的,但不能使用其他子包的资源
① 主包无法引用分包内的私有资源
② 分包之间不能相互引用私有资源
③ 分包可以引用主包内的公共资源
这里的出处参考:
https://www.yii666.com/blog/376774.htmlwww.yii666.com/blog/376774.html
https://www.yii666.com/blog/376774.htmlwww.yii666.com/blog/376774.html
主包:即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;
分包:是根据pages.json的配置进行划分。
加载小程序的时候先加载主包,当需要访问分包的页面时候才加载分包内容
分包的页面可以访问主包的文件,数据,图片等资源
在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,会把对应分包自动下载下来,下载完成后再进行展示。此时终端界面会有等待提示。
在pages.json中新建数组"subPackages",数组中包含两个参数:1.root:为子包的根目录,2.pages:子包由哪些页面组成,参数同pages;
注意:主包和分包是不能再同一目录下,在构建uniapp项目时,可以考虑一下目录结构,以便后期进行分包;
整个小程序所有分包大小不超过 20M
单个分包/主包大小不能超过 2M
1、合理规划分包,开始时就细分分包,尽量少在主包放大文件
2、减少项目的层级,合理归分层级,同时可以提高项目的运行速度
3、静态资源全部cdn加载
4、公共组件库
5、公共CSS库,尽量做到一次代码多次使用,避免重复多余的CSS
6、使用稳定全面的UI库,可以大幅度减少CSS的用量
7、外部较大的js文件,尽量减少使用,非用不可的话全部放到分包里去加载使用
8、主包不可以引用分包内文件,分包仅可引用自身目录内的文件,分包与分包间文件无法互相引用
9、要清楚的是分包是一种不得已而为之的手段,确保在分包前项目中静态资源已优化完毕,且没有大量注释或无用代码也是一种手段
10、静态资源尽量放到服务器上 和公司后端人员沟通 将图片地址尽量放到服务器上 就不占用本地资源空间
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。