流加載是什么

2020-02-11 17:33 更新

用一句話來解釋 流加載,那就是“下載程序包的同時(shí)加載包內(nèi)的文件”,下載與加載并發(fā)可以加速小程序首次無緩存啟動(dòng)的時(shí)間。

為了提升小程序加載速度,我們做了下列改動(dòng):


流加載 1 期:實(shí)現(xiàn)下載與加載同步

使用 ttpkg 包替代 zip 包

在流加載方案之前,小程序的文件都是壓縮到 zip 包內(nèi)的,盡管 zip 包的體積更小,但 zip 包內(nèi)的文件需要等完整的 zip 包下載好后才能解壓出來使用,解壓也需要時(shí)間。

在流加載方案中,我們改用 ttpkg 包來裝載小程序的文件,ttpkg 包是未壓縮過的二進(jìn)制文件包,可以直接讀取包內(nèi)指定區(qū)域的二進(jìn)制數(shù)據(jù)。ttpkg 包相比于壓縮的 zip 包體積會(huì)更大,通過開啟 CDN 智能壓縮服務(wù),在 ttpkg 包請求過程中,服務(wù)器對返回的 ttpkg 數(shù)據(jù)進(jìn)行 gzip 編碼,壓縮重復(fù)的字符串等,可以減少 ttpkg 包的傳輸大小,從而縮短下載時(shí)間。

下圖可見 ttpkg 包內(nèi)的文件分布結(jié)構(gòu),僅舉例,不同的小程序文件順序可能不同。

圖片名稱

資源加載時(shí)機(jī)提前

在 ttpkg 格式程序包的支持下,我們不必等待包下載完成后才去加載資源,資源加載的時(shí)機(jī)得以提前。

流加載優(yōu)化前后的啟動(dòng)階段流程分別如下:

優(yōu)化前

圖片名稱

優(yōu)化后

圖片名稱

假設(shè)某個(gè)版本的小程序 A 在改造前后包內(nèi)文件不變,資源加載順序相同,提前加載文件可以使得小程序首屏渲染更快出現(xiàn)。

類似的,我們可以提前加載某些不在 ttpkg 包內(nèi)的文件來減少加載文件這塊的耗時(shí),比如:

  • tma-core.js、tmg-core.js 預(yù)加載
  • page-frame.html 預(yù)加載
  • webview.js 預(yù)加載

game.js 拆分

我們還對小游戲的 game.js 文件進(jìn)行了拆分,支持按需加載拆分后的 js 文件。

  • 優(yōu)化前:game.js 文件包含著所有游戲場景的邏輯,這在啟動(dòng)階段就會(huì)全量加載到 JSC 環(huán)境中,但實(shí)際上一些加載進(jìn)來的游戲邏輯尚用不到。
  • 優(yōu)化后: game.js 拆分出多個(gè)散文件,在 game.js 內(nèi)根據(jù)散文件的使用先后順序,邊運(yùn)行邊按需加載,在理想情況下,不需要加載所有拆出的散文件即可渲染出首幀。

圖片名稱

如上圖,優(yōu)化后從 game.js 拆出了 pageA.js、pageB.js、pageC.js、pageD.js,若該小游戲僅需要加載 pageA、pageB、pageC.js 即可渲染出首屏,那我們就省下了下載以及加載 pageD.js 的時(shí)間。

副作用

當(dāng)小程序無緩存冷啟動(dòng),流加載的邊下邊加載在特定情況下也會(huì)給我們帶來副作用,比如:

  • 啟動(dòng)階段,ttpkg 包已下載的部分足以展示出首屏界面,但用戶在操作首屏界面的過程中,忽然發(fā)生斷網(wǎng)等問題導(dǎo)致 ttpkg 下載失敗,此時(shí)會(huì)彈出一個(gè)報(bào)錯(cuò)窗口打斷用戶操作,用戶需要重啟小程序
  • 用戶使用階段, ttpkg 包中的某個(gè)圖片可能因?yàn)樯形聪螺d完,而遲遲無法展示出來;或者小游戲 ttpkg 中的某個(gè) js 文件沒下載完,而發(fā)生卡頓


流加載 2 期:小程序包體改造優(yōu)化

包體改造主要是優(yōu)化小程序的首屏加載時(shí)間,以下方面做了優(yōu)化:

app-service.js 拆分

對齊小游戲 game.js 的拆分優(yōu)化,把小程序不同界面的 js 邏輯從 app-service.js 文件中拆分出來, 各界面打開時(shí)再按需加載,減少了首屏加載過程中所需要加載的內(nèi)容,可縮短首屏展示時(shí)間。

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

圖片名稱

WebView 預(yù)加載通用 page-frame.html、webview.js

除了實(shí)現(xiàn)流加載做到下載與加載并發(fā)來縮短首屏展示時(shí)間外,在文件加載階段,我們會(huì)把某些特定文件提前預(yù)加載好,并且確保這些文件不在 ttpkg 包內(nèi),這樣就不會(huì)被 ttpkg 下載過程所影響。

最佳理想情況下,可達(dá)到的效果圖:

圖片名稱

WebView 的創(chuàng)建、page-frame.html 和 webview.js 的加載都是必須的操作,所以在小程序啟動(dòng)前預(yù)創(chuàng)建、預(yù)加載好,可以一定程度減少小程序啟動(dòng)后再去加載他們的消耗的時(shí)間。

為了能做到預(yù)加載,流加載二期,就把 ttpkg 中的 page-frame.html(它包含所有界面的結(jié)構(gòu))精簡成各界面通用的 page-frame.html, 并放到我們的 jssdk 基礎(chǔ)庫中。而 jssdk 基礎(chǔ)庫都是內(nèi)置在 SDK 中的,不強(qiáng)依賴于下載過程。


流加載 3 期:ttpkg 包中文件分布順序的優(yōu)化

為了達(dá)到流加載的最大收益,我們還在要做 ttpkg 包中文件分布順序的優(yōu)化。

舉個(gè)例子,如下是某個(gè)小游戲 ttpkg 包文件分布圖,從低到高位分別安放著以下文件:

圖片名稱

當(dāng)游戲啟動(dòng)后,ttpkg 下載的大小剛好包含 game.js 文件,于是小游戲開始加載執(zhí)行 game.js, 但 game.js 中又去加載了 gameB.js,這種情況下,小游戲就會(huì)停止等待 ttpkg 繼續(xù)下載,直到包下載大小超過了 gameB.js 才會(huì)繼續(xù)執(zhí)行。

ttpkg 包內(nèi)文件分布順序 的優(yōu)化就是為去調(diào)整文件在 ttpkg 包中的坐落位置,盡可能讓文件分布順序與小程序/游戲啟動(dòng)執(zhí)行要加載的文件順序一致。這樣就可以減少在啟動(dòng)無緩存小程序的過程中, 出現(xiàn)要加載某個(gè)尚未下載到的文件而停止等待的場景。

后臺每日根據(jù)上報(bào)的文件訪問順序埋點(diǎn),按順序以及頻率進(jìn)行排序,優(yōu)化 ttpkg 的文件順序,生成新的 ttpkg。該操作無需開發(fā)者做任何操作。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號