主要目標
如果小程序在打開新頁面時需要通過網絡請求從接口中獲取所用的數據,在請求完成之前頁面都會因為沒有數據而呈現一片空白,解決這個問題常見的解決方案有:
-
先使用從緩存中取出上一次的數據,等到請求結束后再使用請求得到的數據(這個對於變動不大的數據是完全可行的,但是對於變動大或者以內容為主的功能並不合適)
-
在加載時顯示骨架屏(知乎和餓了么的移動端有的地方是這么做的)
-
前一個頁面預加載下一個頁面的數據,達到秒開的效果
很明顯,緩存並不廣泛適用,骨架屏只是一個比loading圖標好看的占位符,而預加載能夠完全符合要求。
但是在小程序中如果要實現預加載的功能便需要在頁面中操作其他頁面(包括還沒有創建實例的頁面),會使代碼嚴重耦合,不利於維護,需要一個更清晰的結構來實現預加載功能。
設計思路
-
小程序中實現預加載能力的關鍵便是能夠調用其他頁面的函數,需要獲取其他頁面對象。但是部分頁面還沒有加載出來,getCurrentPages方法獲取不到,因此需要把被預加載的頁面的PageOption(就是在創建頁面時傳入Page函數的對象)給保存起來
-
那些沒有被創建的頁面並沒有setData方法,需要模擬一個setData方法,把獲取到的數據暫存起來,在onLoad階段再調用 setData呈現到視圖上
-
頁面應當可以主動被預加載,但是在沒有被預加載的時候也應該能夠正常打開
源碼實現
preload源碼依賴於mp-extend提供的全局混入能力。
-
重寫Page函數,保存需要預加載頁面的PageOption
-
擴展小程序頁面的生命周期 onPreload,與onLoad功能功能基本相同,能夠接收來自url的參數,在主動預加載時被調用
-
提供 this.$preload(url) 方法,用於主動預加載某個頁面,如果頁面實例未創建就把預加載的數據保存起來,等到頁面onLoad時再調用setData呈現到視圖上