必看!揭祕抖音小程式效能提升之流載入

語言: CN / TW / HK

小知識,大挑戰!本文正在參與“程式設計師必備小知識”創作活動。

作者:抖音小程式iOS團隊同學

一、流載入是什麼?

用一句話來解釋流載入,那就是“下載程式包的同時載入包內的檔案”,下載與載入併發可以加速小程式首次無快取啟動的時間。

二、實現方案

1.1 使用pkg包替代zip包

流載入方案之前,小程式的檔案都是壓縮到zip包內的,儘管zip包的體積更小,但zip包內的檔案需要等完整的zip包下載好後才能解壓出來使用,解壓也需要時間。

流載入方案中,我們改用pkg包來裝載小程式的檔案,pkg包是未壓縮過的二進位制檔案包,可以直接讀取包內指定區域的二進位制資料。pkg包相比於壓縮的zip包體積會更大,通過開啟CDN智慧壓縮服務,在pkg包請求過程中,伺服器對返回的pkg資料進行gzip編碼,壓縮重複的字串等,可以減少pkg包的傳輸大小,從而縮短下載時間。

下圖可見pkg包內的檔案分佈結構,僅舉例,不同的小程式檔案順序可能不同。 image.png

1. | 檔案識別符號"PKG"(8位元組) | 檔案版本號(8位元組) | 2. | 擴充套件資訊長度(8位元組) | 擴充套件資訊 | 3. | 所包含的檔案數量(8位元組)| 4. | 檔案 1 檔名長度(2位元組) | 檔案 1 檔名 | 檔案 1 偏移量(4位元組) | 檔案 1 大小(4位元組) | 5. | 檔案 2 檔名長度(2位元組) | 檔案 2 檔名 | 檔案 2 偏移量(4位元組) | 檔案 2 大小(4位元組) | 6. | ... | 7. | 檔案 1 二進位制內容 | 檔案 2 二進位制內容 | ...|

1.2 資源載入時機提前

在pkg格式程式包的支援下,我們不必等待包下載完成後才去載入資源,資源載入的時機得以提前。

流載入優化前後的啟動階段流程分別如下: image.png

image.png

假設某個版本的小程式A在改造前後包內檔案不變,資源載入順序相同,提前載入檔案可以使得小程式首屏渲染更快出現。

1.3 小程式包體改造優化

包體改造主要是優化小程式的首屏載入時間,把app-service.js進行拆分,把小程式不同介面的js邏輯從app-service.js檔案中拆分出來, 各介面開啟時再按需載入,減少了首屏載入過程中所需要載入的內容,可縮短首屏展示時間。

如下圖所示,拆分前,app-service.js包含拆出來的pageA、pageB、pageC的js邏輯。拆分後,首屏僅需要下載完“瘦身後”的app-service.js以及首頁pageA.js再載入即可。 image.png

1.4 pkg檔案順序重排優化

為了達到流載入的最大收益,我們還做了pkg包中檔案分佈順序的優化

舉個例子,如下是某個小程式pkg包檔案分佈圖,從低到高位分別安放著以下檔案: image.png

當小程式啟動後,pkg下載的大小剛好包含game.js檔案,於是小程式開始載入執行game.js, 但game.js中又去載入了gameB.js,這種情況下,小程式就會停止執行,等待pkg繼續下載,直到包下載大小超過了gameB.js才會繼續執行。

pkg包內檔案分佈順序的優化就是為去調整檔案在pkg包中的坐落位置,儘可能讓檔案分佈順序與小程式啟動執行要載入的檔案順序一致。這樣就可以減少在啟動無快取小程式的過程中, 出現要載入某個尚未下載到的檔案而停止等待的場景。

後臺每日根據上報的檔案訪問順序埋點,按順序以及頻率進行排序,優化pkg的檔案順序,生成新的pkg。該操作無需開發者做任何操作。