Taro 小程序開發性能優化實踐
我們團隊在利用 Taro 進行秒送頻道小程序的同時,一直在探索性能優化的最佳實踐。隨着需求的不斷迭代,項目中的性能問題難免日積月累,逐漸暴露出來影響用戶體驗。適逢雙十一大促,我們趁着這個機會統一進行了 Taro 性能優化實踐,現總結如下,希望能爲大家在日程的開發中提供借鑑,助力大促。
優化前性能表現
性能表現主要從兩方面進行衡量,第一個是頁面加載時間,其次是頁面流暢程度。
頁面加載時間我們通過兩個維度進行量化,其一是關鍵點位打點記錄時長,具體的點位有:
記錄點位並計算時間間隔,統計出的量化時間表如下:
冷啓動(初次加載小程序包)
熱啓動(已安裝小程序包,退出微信後重新進入)
其二,實際上通過代碼 log 打點存在很多問題,比如有些關鍵時間點沒有時機進行上報,無法真實地反映出用戶體驗的實際情況,所以最真實的使用場景還是親自掐表進行時間統計。
掐秒錶:分段 1(分包加載),分段 2(緩存佔位獲取定位,發起 cms 請求),分段 3(cms 加載完成),總時長。
設備:中端 (iPhone11)
問題分析
根據統計結果,很可以看出容易,目前秒送頻道頁存在的主要問題主要集中於以下幾個方面:
-
分包加載速度慢,導致首屏耗時偏長。
-
接口請求時長過長。
-
feeds 渲染耗時偏長。
需要根據存在的問題,針對性地採取對應處理方案。
優化實踐
1. 切換 Skyline 渲染引擎
爲了解決首屏耗時較長的問題,我們經過調研,決定採用 Skyline 引擎來進行優化。
Skyline 是微信官方提供的渲染引擎,目標是進一步優化小程序性能,提供更爲接近原生的用戶體驗。其使用更精簡高效的渲染管線,並帶來諸多增強特性,讓 Skyline 擁有了更接近原生渲染的性能體驗。
Skyline 創建了一條渲染線程來負責渲染任務,並在 AppService 中劃出一個獨立的上下文,來運行之前 WebView 承擔的 JS 邏輯、DOM 樹創建等邏輯。
這種新的架構相比原有的 WebView 架構,有以下特點:
• 界面更不容易被邏輯阻塞,進一步減少卡頓
• 無需爲每個頁面新建一個 JS 引擎實例(WebView),減少了內存、時間開銷
• 框架可以在頁面之間共享更多的資源,進一步減少運行時內存、時間開銷
• 框架的代碼之間無需再通過 JSBridge 進行數據交換,減少了大量通信時間開銷
而與此同時,這個新的架構能很好地保持和原有架構的兼容性,可以很大程度上降低首屏的渲染耗時。
在實際 Skyline 適配的過程中,我們對遇到的問題進行了記錄:
1. 利用 backgroundPosition,backgroundImage 和 height 裁剪背景圖片的時候,backgroundPosition 不可以使用 calc 運算符:
目的:裁剪圖片從底部開始,向上,高度爲 gradientHeight 的部分
原寫法:
style={{
backgroundPosition: `center calc(100% + ${getPx(gradientHeight)})`
}} >
適配寫法:
style={{
backgroundPosition: `center bottom -${gradientHeight}px`
}} >
2. 在需要吸頂展示的場景,position: sticky 不適用,需要改寫:
目的:滾動到距頂部 statusBarHeight 的時候吸頂展示
原寫法:
style={{
position: sticky,
top: statusBarHeight,
}} >
適配寫法
<ScrollView type="list">
<StickySection pushPinnedHeader={false}>
<StickyHeader offsetTop={statusBarHeight}>
<View className={styles.view}>
...
</View>
</StickyHeader>
</StickySection>
</ScrollView>
3. 子視圖節點有用到 position: absolute 的場景,根結點需要設置 position: relative
4. 在視圖設置全圓角的時候,單獨設置某一變的顏色,會使圓角失效:
.loading {
border-radius: 100%;
border-top-color: transparent;
}
現象:
5.position: fixed 屬性失效:使用 position:
absolute 和 position: relative 按需代替
6.z-index 只在同層級之間有效,跨層級無效:
如果實在無法提高層級,可以考慮使用: root-portal 組件
7. 所有節點默認是 relative,可能導致 absolute 不準 / margin-top 無效:
按實際情況調整 UI。如果遇到節點下的第一個 margin-top 無效,可以在前面加一個佔位的的 view
最終適配完成後的優化效果如下
冷啓動:
熱啓動:
- 資源位延遲加載
feeds 樓層存在着渲染時長偏長的問題,最主要的問題集中在店帶品樓層上:
該樓層帶有商品列表,列表中的商品每一個都會渲染一個資源位,數目在 15 到 20 個不等,這樣的樓層會下發 13 個左右,且每次都會在接口下發後一次性全部渲染,導致渲染的資源位數目暴增。
本次優化對商品資源位的加載進行了優化,首屏只最多渲染 6 個:
其餘商品在滑動觸底是懶加載。
<ScrollView
...
onScrollToLower={handleScrolltolower}
...
/>
const handleScrolltolower = useCallback(e => {
if (loadMoreImg.current == false) {
loadMoreImg.current = true
//加載剩餘圖片 setDatasource)
}
}, [loadMoreImg])
以此方式來減少渲染工作量,提高渲染速度。底部的 feeds 商品資源位也採用相同的處理方式,首屏最多加載 6 個:
3. 多團隊溝通優化
除了使用懶加載的方式,我們也積極與產品和 UED 團隊溝通,針對店帶品的使用場景溝通解決方案。最終確定可以將首屏下發的樓層數從 13 個調整爲 9 個,進一步降低渲染壓力,提升 feeds 部分的渲染速度。
在實際優化實踐中,往往與其他團隊進行溝通,是最有效的優化方式,大家可以多借鑑一下。
4. 圖片資源優化
圖片資源尺寸過大,會導致圖片下載緩慢,資源位白屏,用戶體驗差。以往網管在進行商品圖片下發的時候,無論是店帶品樓層的商品還是商品詳情頁展示的商品大圖,採用的都是同一套尺寸較大的圖片,這就導致在店帶品樓層商品列表過多時,圖片下載過程等待時間過長。經過與後端團隊,產品和 UED 團隊積極溝通,確定了一套 3 尺寸圖片方案:
產品配置圖片的時候,會配置大、中、小三種尺寸的圖片,網關在下發時會根據資源位的類型區別下發,針對店帶品樓層、feeds 商品這種樓層,僅下發小尺寸圖片,以減小接口請求數據量以及圖片下發時間,極大地提高了圖片夾雜速度。
5. 接口請求邏輯改造
秒送頻道頁涉及到兩個接口請求,分別是主接口和 feeds 數據接口,之前因爲代碼結構的原因,兩個接口採用了串行請求的方式做請求。這次的優化經過方案評審,將串行改爲並行,並將兩個接口返回的結果進行隔離,分批渲染,從而降低了整體接口請求的時長。
優化成果
經過一系列優化,在接口請求總時長,feeds 渲染提升非常明顯,首屏加載速度有了很大提升:
根據掐秒錶的結果,也能夠最直觀的感覺出整體開啓速度的提升:
結語
Taro 小程序開發的性能優化實踐,不僅涉及到前端代碼優化,還涉及到了多個團隊之間的溝通配合,好的代碼習慣也不是一朝一夕就能養成的,優化也需要日積月累,不斷持續地推進,希望這篇文章可以幫助到大家,助力大促期間的用戶體驗改進。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/fIL-wCeXinjbWmGD5pT6mg