W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
小程序啟動是小程序用戶體驗(yàn)中極為重要的一環(huán),啟動耗時(shí)過長會造成小程序用戶流失。
本章節(jié)的啟動只包括小程序冷啟動,不包括小程序后臺切前臺的熱啟動。
在進(jìn)行啟動優(yōu)化之前,先簡單介紹以下小程序的啟動過程。在小程序啟動過程中,主要包括以下幾個(gè)方面:
在用戶訪問小程序時(shí),微信客戶端需要從微信后臺獲取小程序的配置、版本、權(quán)限等相關(guān)信息,以對小程序進(jìn)行必要的版本管理、權(quán)限控制和校驗(yàn)等。
對啟動耗時(shí)的影響
信息的獲取和更新會影響小程序的啟動耗時(shí),尤其體現(xiàn)在用戶首次訪問小程序時(shí)。
為了在盡量降低影響啟動耗時(shí)的情況下保證信息的實(shí)時(shí)性,這些信息會在本地緩存,并通過一定的機(jī)制定期進(jìn)行更新。
在執(zhí)行小程序代碼之前,微信客戶端需要準(zhǔn)備小程序運(yùn)行的基礎(chǔ)環(huán)境。
小程序的運(yùn)行環(huán)境包括小程序進(jìn)程、原生部分的 UI 元素(如 導(dǎo)航欄、tabBar等)、渲染頁面使用的 WebView 容器、運(yùn)行開發(fā)者 JS 代碼的 JS 引擎、小程序基礎(chǔ)庫等等。
對啟動耗時(shí)的影響
運(yùn)行環(huán)境的準(zhǔn)備耗時(shí)較長,對小程序的啟動耗時(shí)有明顯影響。
為了盡可能的降低運(yùn)行環(huán)境準(zhǔn)備對啟動耗時(shí)的影響,微信客戶端會根據(jù)用戶的使用場景和設(shè)備資源的使用情況,提前對運(yùn)行環(huán)境進(jìn)行部分地預(yù)加載。但由于受到設(shè)備資源和操作系統(tǒng)調(diào)度的影響,目前很難保證每次小程序啟動時(shí)都有預(yù)加載的環(huán)境。
小程序啟動時(shí)需要從服務(wù)器獲取代碼包地址、下載小程序代碼包,并對代碼包進(jìn)行校驗(yàn)。根據(jù)小程序頁面所在分包和使用的插件不同,一次啟動可能需要下載多個(gè)代碼包或插件包。
當(dāng)小程序版本發(fā)生更新時(shí),微信客戶端還需要對代碼包進(jìn)行增量更新。
對啟動耗時(shí)的影響
下載耗時(shí)是啟動耗時(shí)中的重要瓶頸,與代碼包或增量包的體積正相關(guān)。微信采用 ZSTD 算法對小程序代碼包進(jìn)行壓縮,以盡可能降低下載過程中傳輸?shù)臄?shù)據(jù)量。
考慮到包大小對用戶體驗(yàn)的影響,平臺限制單個(gè)代碼包的大小上限為 2M。代碼包上限的增加對于開發(fā)者來說,能夠?qū)崿F(xiàn)更豐富的功能,但對于用戶來說,也增加了下載流量和本地空間的占用。為了保證啟動速度,開發(fā)者應(yīng)該盡可能的控制代碼包大小。
小程序啟動時(shí)需要從代碼包內(nèi)讀取小程序的配置和代碼,并注入到 JS 引擎中。在主包代碼注入過程中,會觸發(fā)小程序的 App.onLaunch 和首次 App.onShow 生命周期。在開發(fā)者代碼注入完成后,框架側(cè)會根據(jù)用戶訪問的頁面進(jìn)行一些頁面數(shù)據(jù)初始化工作,觸發(fā)首頁的 Page.onLoad, Page.onShow 事件。
對啟動耗時(shí)的影響
開發(fā)者代碼的注入耗時(shí)直接影響小程序的啟動耗時(shí)。在主流的 JS 引擎中,代碼注入耗時(shí)包括編譯和執(zhí)行等環(huán)節(jié),代碼量、同步接口調(diào)用和一些復(fù)雜的計(jì)算,都會影響注入耗時(shí)。
由于首頁渲染需要使用邏輯層發(fā)送的數(shù)據(jù),如果開發(fā)者代碼注入耗時(shí)過長,也會延遲首頁渲染開始的時(shí)間。
在部分平臺上,微信客戶端會使用 V8 引擎的 Code Caching 技術(shù)對代碼編譯結(jié)果進(jìn)行緩存,降低二次注入時(shí)的編譯耗時(shí)。
開發(fā)者的 wxss 和 wxml 會經(jīng)過編譯注入到渲染層,包含頁面渲染需要的頁面結(jié)構(gòu)和樣式信息。渲染層的注入耗時(shí)主要和頁面結(jié)構(gòu)復(fù)雜度和使用的自定義組件數(shù)量有關(guān)。
渲染層和邏輯層的開發(fā)者代碼注入是并行進(jìn)行的。
對啟動耗時(shí)的影響
由于首頁渲染需要使用渲染層的頁面結(jié)構(gòu)和樣式信息,如果開發(fā)者代碼注入耗時(shí)過長,會延遲首頁渲染開始的時(shí)間。
在開發(fā)者代碼注入完成后,結(jié)合邏輯層得到的數(shù)據(jù)和渲染層得到的頁面結(jié)構(gòu)和樣式信息,小程序框架會進(jìn)行小程序首頁的渲染,展示小程序首屏,并觸發(fā)首頁的 Page.onReady 事件。Page.onReady 事件觸發(fā)標(biāo)志小程序啟動過程完成。
對啟動耗時(shí)的影響
首頁渲染耗時(shí)主要受頁面結(jié)構(gòu)和參與渲染的數(shù)據(jù)量影響。
在討論小程序啟動耗時(shí)時(shí),需要明確幾個(gè)概念:
從開發(fā)者角度看,小程序首屏渲染完成的標(biāo)志是首頁 Page.onReady 事件觸發(fā)。
從框架的角度來說,小程序的首屏的內(nèi)容是基于小程序的初始數(shù)據(jù),以及在渲染開始前到達(dá)的 setData 數(shù)據(jù)渲染的。
首屏渲染完成不表示小程序頁面一定有完整內(nèi)容,開發(fā)者觸發(fā)的 setData(例如通過 wx.request 異步請求數(shù)據(jù))不一定能參與到首屏渲染中。
由于框架和啟動流程的差異,小程序定義的首屏渲染完成不等同于瀏覽器的 load 事件。
從用戶點(diǎn)擊訪問小程序到小程序首屏渲染完成(首頁 Page.onReady 事件觸發(fā))。
小程序首屏渲染完成 PV 與 用戶點(diǎn)擊訪問小程序 PV 的比值。流失率 = 1 - 打開率
在啟動流程中,小程序代碼包準(zhǔn)備、開發(fā)者代碼注入和首頁渲染是與開發(fā)者相關(guān)的,開發(fā)者可以進(jìn)行一定的優(yōu)化工作。其他部分目前開發(fā)者暫時(shí)無法干預(yù),框架側(cè)負(fù)責(zé)進(jìn)行持續(xù)的優(yōu)化。
代碼包優(yōu)化的核心手段是降低代碼包大小,代碼包大小直接影響了下載耗時(shí),影響用戶啟動小程序時(shí)的體驗(yàn)。
開發(fā)者可以采取以下手段優(yōu)化代碼包大小:
使用 分包加載 是優(yōu)化小程序啟動耗時(shí)效果最明顯的手段。建議開發(fā)者按照功能劃分,將小程序的功能按使用頻率和場景拆分成分包,實(shí)現(xiàn)代碼包的按需加載。
分包加載具有以下優(yōu)勢:
此外,結(jié)合分包加載的幾個(gè)擴(kuò)展功能,可以進(jìn)一步優(yōu)化啟動耗時(shí):
在使用「分包加載」后,雖然能夠顯著提升小程序的啟動速度,但是當(dāng)用戶在使用小程序過程中跳轉(zhuǎn)到分包內(nèi)頁面時(shí),需要等待分包下載完成后才能進(jìn)入頁面,造成頁面切換的延遲,影響小程序的使用體驗(yàn)。分包預(yù)下載便是為了解決首次進(jìn)入分包頁面時(shí)的延遲問題而設(shè)計(jì)的。
但小程序中的某些場景(如廣告頁、活動頁、支付頁等),通常功能不是很復(fù)雜且相對獨(dú)立,對啟動性能有很高的要求。獨(dú)立分包可以獨(dú)立于主包和其他分包運(yùn)行。從獨(dú)立分包中頁面進(jìn)入小程序時(shí),不需要下載主包。建議開發(fā)者將部分對啟動性能要求很高的頁面放到特殊的獨(dú)立分包中。
獨(dú)立分包和分包預(yù)下載可以配合使用,獲得更好的效果,詳情請參考獨(dú)立分包與分包預(yù)下載教程
通過代碼重構(gòu),降低代碼冗余。在使用如 Webpack 等打包工具時(shí),要盡量利用 tree-shaking 等特性去除冗余代碼,也要注意防止打包時(shí)引入不需要的庫和依賴。
避免在代碼包中包含或在 WXSS 中使用 base64 內(nèi)聯(lián)過多、過大的圖片,應(yīng)盡量采用網(wǎng)絡(luò)圖片。代碼包內(nèi)的圖片一般應(yīng)只包含一些體積較小的圖標(biāo)。聲音、視頻等其他類型的資源應(yīng)盡量避免放到代碼包中。
小程序代碼包在下載時(shí)會使用 ZSTD 算法進(jìn)行壓縮,降低下載時(shí)傳輸?shù)臄?shù)據(jù)量。這些資源文件會占用大量代碼包體積,并且通常難以進(jìn)一步被壓縮,對于下載耗時(shí)的影響比代碼文件大得多。
在日常開發(fā)的時(shí)候,我們可能引入了一些新的庫文件,而過了一段時(shí)間后,由于各種原因又不再使用這個(gè)庫了,我們常常會只是去掉了代碼里的引用,而忘記刪掉這類庫文件了。
目前小程序打包是會將工程下所有文件都打入代碼包內(nèi),也就是說,這些沒有被實(shí)際使用到的庫文件和資源也會被打入到代碼包里,從而影響到整體代碼包的大小。
開發(fā)者代碼注入的優(yōu)化可以從優(yōu)化執(zhí)行耗時(shí)和優(yōu)化代碼量兩部分著手。
在小程序啟動流程中,會注入開發(fā)者代碼并順序同步執(zhí)行 App.onLaunch, App.onShow, Page.onLoad, Page.onShow
。在小程序初始化代碼(Page,App 定義之外的內(nèi)容)和啟動相關(guān)的幾個(gè)生命周期中,應(yīng)避免執(zhí)行復(fù)雜的計(jì)算邏輯或過度使用Sync結(jié)尾的同步API,如 wx.getStorageSync,wx.getSystemInfoSync 等。對于 getSystemInfo, getSystemInfoSync 的結(jié)果應(yīng)進(jìn)行緩存,避免重復(fù)調(diào)用。
通常情況下,在小程序啟動時(shí),啟動頁面所在分包和主包(獨(dú)立分包除外)的所有JS代碼會全部合并注入,包括其他未訪問的頁面以及未用到自定義組件,造成很多沒有使用的代碼注入到小程序運(yùn)行環(huán)境中,影響注入耗時(shí)和內(nèi)存占用。
自基礎(chǔ)庫版本 2.11.1 起,小程序支持僅注入當(dāng)前頁面需要的自定義組件和當(dāng)前頁面代碼,以降低小程序的啟動時(shí)間和運(yùn)行時(shí)內(nèi)存。開發(fā)者可以在 app.json 中配置:
{
"lazyCodeLoading": "requiredComponents"
}
注意:添加這項(xiàng)配置后,未使用到的代碼文件將不被執(zhí)行。
大部分小程序在渲染首頁時(shí),需要依賴服務(wù)端的接口數(shù)據(jù),小程序?yàn)殚_發(fā)者提供了提前發(fā)起數(shù)據(jù)請求的能力:
在頁面數(shù)據(jù)未準(zhǔn)備好時(shí)(如需要通過網(wǎng)絡(luò)獲?。?,盡量避免展示空白頁面,應(yīng)先通過骨架屏展示頁面的大致結(jié)構(gòu),請求數(shù)據(jù)返回后在進(jìn)行頁面更新。以提升用戶的等待意愿。
小程序提供了wx.setStorage、wx.getStorage等讀寫本地緩存的能力,數(shù)據(jù)存儲在本地,返回的會比網(wǎng)絡(luò)請求快。如果開發(fā)者基于某些原因無法采用數(shù)據(jù)預(yù)拉取與周期性更新,我們推薦優(yōu)先從緩存中獲取數(shù)據(jù)來渲染視圖,等待網(wǎng)絡(luò)請求返回后進(jìn)行更新。
我們推薦開發(fā)者延遲請求非關(guān)鍵渲染數(shù)據(jù),與視圖層渲染無關(guān)的數(shù)據(jù)盡量不要放在 data 中,加快頁面渲染完成時(shí)間。
小程序管理后臺的性能數(shù)據(jù)還沒有更新,正在規(guī)劃改版中,建議在改版完成前開發(fā)者以小程序助手的性能數(shù)據(jù)為準(zhǔn)。
建議開發(fā)者使用小程序助手中「性能分析」板塊,持續(xù)關(guān)注小程序性能。性能分析從 啟動性能、運(yùn)行性能和網(wǎng)絡(luò)性能 三個(gè)維度提供性能數(shù)據(jù),供開發(fā)者根據(jù)平臺、機(jī)型、網(wǎng)絡(luò)環(huán)境和訪問來源等條件做精細(xì)化分析。掃描下方小程序碼即可立即體驗(yàn)。
目前,小程序助手中只包括微信客戶端 >= 7.0.3 版本的正式版小程序數(shù)據(jù)。
開發(fā)者可以在小程序中根據(jù)自身業(yè)務(wù)需有進(jìn)行性能打點(diǎn),也可以使用 wx.getPerformance ,獲取當(dāng)前小程序性能相關(guān)的信息。
在獲取信息后,開發(fā)者可以自行上報(bào)或使用 wx.reportPerformance 進(jìn)行測速。
小程序工具中提供了體驗(yàn)評分工具,方便開發(fā)者能夠及時(shí)發(fā)現(xiàn)小程序的體驗(yàn)問題。
根據(jù)「啟動流程」一節(jié)介紹的啟動流程來看,影響小程序啟動耗時(shí)的因素眾多,分析小程序啟動性能是一個(gè)比較復(fù)雜的過程。
對于同一個(gè)小程序,以下因素會直接影響平均啟動耗時(shí):
此外,下列情況也會間接影響啟動耗時(shí):
小程序助手中提供了啟動過程中和開發(fā)者相關(guān)的下載耗時(shí)、js注入耗時(shí)和初次渲染耗時(shí)供開發(fā)者優(yōu)化參考。
這里需要注意的是,啟動總耗時(shí) ≠ 下載耗時(shí) + js 注入耗時(shí) + 初次渲染耗時(shí)。在啟動過程中,下載不一定發(fā)生,也不一定只下載一個(gè)代碼包。js 注入耗時(shí)和渲染耗時(shí)也會受緩存更新而發(fā)生波動。
各階段耗時(shí)的下降不一定反應(yīng)在總耗時(shí)的下降。例如小程序新版本發(fā)布后,即使各階段耗時(shí)都下降,下載比例的升高反而可能導(dǎo)致總耗時(shí)的上升。
啟動性能和用戶的等待意愿是影響打開率的兩個(gè)關(guān)鍵因素。在部分場景下,如果用戶等待意愿較低,即使啟動耗時(shí)很低,也不一定能獲得較高的打開率。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: