uniapp分包(詳盡版)

致愛麗絲發表於2020-11-28

PS:本文是筆者對基於uniapp的一小程式專案進行分包後的覆盤文件,不足之處請多多指教。

一:分包相關概念

  1. 本質上是改變專案的路由以及優化專案各個模組的啟動時間的一種優化技術。

  2. 主包與分包的概念

1). 主包:本專案中初始化時所必須的頁面。

專案在啟動時,將從主包進入,分包在使用者未進入時不會載入,只有在進入分包模組時才會載入。
tabbar頁面以及模組間共有的頁面,如果該專案有賬號限制(即非註冊賬號不可進入主介面),也應將登入頁放置在主包內

2). 分包:除主包外的所有頁面都應放置在分包內,為避免讀者混淆,本文會將該分包定義為子包

二:為什麼要分包

優化專案首次啟動的下載時間;小程式預設就是整包(主包)下載,但這會導致整個專案只有在全部載入完畢後才會回顯到使用者眼前,這樣雖然可以使用載入動畫進行優化,但也會有部分可能導致使用者流失;

防止專案超出小程式官方對小程式專案打包後的大小限制;

若不分包,整個程式最大限制不能超過2M,分包後,整個專案(包含主包+子包)最大不能超過16M,單個包不能超過2M (這樣就規避了專案最大不得超過2m的限制)

三: 分包基本邏輯

  • 靜態檔案:分包下支援 static 等靜態資源拷貝,即分包目錄內放置的靜態資源不會被打包到主包中,也不可在主包中使用
  • js檔案:當某個 js 僅被一個分包引用時,該 js 會被打包到該分包內,否則仍打到主包(即被主包引用,或被超過 1 個分包引用)
  • 自定義元件:若某個自定義元件僅被一個分包引用時,且未放入到分包內,編譯時會輸出提示資訊

四: 分包步驟詳解

PS: 由於筆者僅做了微信小程式分包,因而以下也僅對面向微信小程式的uniapp專案有效

PS: 筆者是tabbar頁作為單模組劃分子包,即每個tabbar均作為一個子包模組

  1. (manifest.json ) 開啟分包優化

新增相關欄位

// "mp-weixin"
"optimization":{ 
      "subPackages":true //是否啟用分包優化
}

  1. (pages.json) 宣告專案分包結構
  • pages:

原則:pages內只允許存放tabbar頁面路由,以及各個子包所共有的頁面頁面,如果有登入頁且不登入無法進入主頁面,該登入頁面路由也應放置在pages路由內

  • subPackages:

定義:單個模組內的除主包內檔案的所有的檔案,

比如: 假設一個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如下:

這樣便完成了配置的第二步

  1. 更換各個頁面路由

筆者之前一直強調的分包越早越好的原因就在於此,一但專案到了微信2m限制,則會直接導致專案無法在開發者工具中執行,雖然分包可以在整個專案週期任一進度進行,但是需花費的時間是與專案進度是成正比的,即專案進度越到尾期,則分包需要花費的時間也就越長,筆者對此深有體會(流眼淚.jpg)
如果在專案中末期才進行分包,此時需要開發者站在整個專案角度上,對每個模組,每個頁面,每個網路請求都要了然於胸,可以藉助於思維導圖工具,將專案所有模組所有頁面都列出來,剔除tabbar頁面和模組間共有頁面,然後將剩餘頁面填充至指定子包目錄下,並在subPackages目錄下宣告該頁面路徑,並且,開發者必須要重新定義路由跳轉路徑以及元件引入方式,這一點極為繁瑣,且極易出錯造成損失,因而建議開發者在走這一步前預先做好備份。

匯入元件路徑建議直接更換成以@開頭的絕對路徑來替換省略號開頭的相對路徑,防止以後可能再次發生的變更

跳轉路由也應換成絕對路徑,(路由更換後跳轉失敗? 請點選這裡

在本過程中,可能會出現各種引用錯誤或者無法跳轉的問題,此時需要開發者心態平緩,並一定要謹慎檢查

如果在開發者工具中執行整個專案顯示沒有報錯資訊,則可以在真機除錯,如果有短時彈框 “ 載入模組中 ”,則表示分包成功

那麼問題來了:我不想使用者看到這幾個醜陋的字,該怎麼做?

出現這幾個字的原因是由於使用者剛進入的介面必定是主包,而在使用者進入分包的時候,由於分包資源還未下載,所以微信官方便貼心的提示使用者正在載入分包資源
筆者:微信我謝謝你呀!(超大聲嗶嗶)
那麼接下來要說的,就是關於這類問題的解決辦法: 分包預載入

  1. (pages.json)實現分包預載入

定義:在使用者進入某個頁面時,同時靜默下載跟該頁面有關的子包檔案

與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控制檯會輸出以下資訊:

  1. 幾點原則
  1. 主包可以引用分包內檔案,分包僅可引用自身目錄內的檔案,分包與分包間檔案無法互相引用,
  1. 要清楚的是分包是一種不得已而為之的手段,確保在分包前專案中靜態資源已優化完畢,且沒有大量註釋或無用程式碼也是一種手段

-------------------------假裝這是一條分割線----------------------------------------------------------

這篇文章是筆者在覆盤專案時的心得,不足之處歡迎在評論區指教,不勝感激

以上。

相關文章