PS:本文是筆者對基於uniapp的一小程序項目進行分包後的覆盤文檔,不足之處請多多指教。html
本質上是改變項目的路由以及優化項目各個模塊的啓動時間的一種優化技術。vue
主包與分包的概念json
1). 主包:本項目中初始化時所必須的頁面。小程序
項目在啓動時,將從主包進入,分包在用戶未進入時不會加載,只有在進入分包模塊時纔會加載。
tabbar頁面以及模塊間共有的頁面,若是該項目有帳號限制(即非註冊帳號不可進入主界面),也應將登陸頁放置在主包內微信小程序
2). 分包:除主包外的全部頁面都應放置在分包內,爲避免讀者混淆,本文會將該分包定義爲子包數組
優化項目首次啓動的下載時間;小程序默認就是整包(主包)下載,但這會致使整個項目只有在所有加載完畢後纔會回顯到用戶眼前,這樣雖然可使用加載動畫進行優化,但也會有部分可能致使用戶流失;微信
防止項目超出小程序官方對小程序項目打包後的大小限制;網絡
若不分包,整個程序最大限制不能超過2M,分包後,整個項目(包含主包+子包)最大不能超過16M,單個包不能超過2M (這樣就規避了項目最大不得超過2m的限制)app
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控制檯會輸出如下信息:
- 主包能夠引用分包內文件,分包僅可引用自身目錄內的文件,分包與分包間文件沒法互相引用,
- 要清楚的是分包是一種不得已而爲之的手段,確保在分包前項目中靜態資源已優化完畢,且沒有大量註釋或無用代碼也是一種手段
-------------------------僞裝這是一條分割線----------------------------------------------------------
這篇文章是筆者在覆盤項目時的心得,不足之處歡迎在評論區指教,不勝感激
以上。