从“等等”到“秒开”再到“直开”,是什么让闲鱼社区相见恨晚?
作者:閑魚技術-頌晨
背景
閑魚前端頁面的性能常常被人念叨,凡跳轉、必跳魚 的印象深入人心,部分頁面甚至需要跳四五下才能打開,最近我們對閑魚前端頁面系統性的做了些優化,由于閑魚前端技術棧相對多元,不同棧技術原理各不相同,優化方案也有所差異,本文主要介紹目前閑魚占比較重的 Weex 頁面的優化過程。
閑魚 Weex 頁面多以前端渲染為主,其打開過程與 Web 頁面略微相近,大致分為以下幾個階段:
我們將「從開始加載(navigationStart)到屏幕首次 paint(繪制)像素內容」的這段時間稱為 白屏時間(FP),將「從開始加載(navigationStart)到首屏內容全部渲染完成」的這段時間稱為 首屏時間(FSP),受限于統計口徑,目前 Weex 下的首屏時間是不包含圖片下載及后續過程的。
優化前后
我們拿閑魚的直播頻道頁和玩家頻道頁作為參考,通過錄屏的方式看下優化前后的對比:
?
通過錄屏分幀的方式我們統計了下這兩個頻道頁在不同系統不同機型下的首屏時長:
可以看到,優化前 iOS、Android 主流機型上的首屏時間都要超過 2s,低端機甚至要 3-5s,優化后各機型的首屏時間均大幅下降,低端機首屏時長控制到了 2s 內,中高端機近乎直開。
拆解分析
確定優化方案前我們對現有的 Weex 頁面做了拆解分析,從結果來看,以下幾個因素對首屏時間的影響較大:
優化方案
基于上面的分析調研,我們初步把優化方案定為四層:
按照預期優化效果,Weex 頁面的打開過程是這樣的:
體現在上述的四層結構中,主要包含以下幾個優化點:
Bundle 離線
具體實現是將 Weex Bundle 以資源包為單位、以 URL 前綴為索引,通過一定的更新策略離線到客戶端本地,之前的更新策略主要有 訪問后安裝、啟動安裝** 兩種,對應的更新時機如下:
這套機制在容器層有統一的方案支撐,但是包命中率一直不高(25% - 55%),導致最終效果差強人意,分析后發現默認的更新策略(訪問后安裝)與頁面回訪率強相關,閑魚的前端頁面大都是頻道導購型的頁面,回訪率天然不高,所以包命中率相對應也不會高。
本次優化主要是對更新策略進行了擴展,增加了 “閑時安裝” 的更新策略:會在定時更新期間主動安裝,如果安裝后未使用,則會在一周之后淘汰;如果一周內使用過,則進入常規的更新淘汰機制(一個月未使用淘汰)。
在 “閑時安裝” 的更新策略上線后,包命中率大幅提升(穩定后 90% 左右),頁面性能也得到了顯著提升:
不依賴首屏接口渲染的頁面甚至可以達到「直開」:
?
數據預取
傳統的首屏數據請求都是在 Bundle 解析完以后發起的,首屏數據返回后渲染頁面,是個典型的串行過程。
本次優化中我們把這個串行的過程并行化了:
時序圖如下:
特殊情況下的時序圖:
具體的技術細節本文不再贅述,數據預取的優化策略上線后,首屏時間也得到了一定程度的提升,如下(iOS 側由于各優化策略并行上線,沒能做到單一變量采集性能數據,暫以 Android 側為參考):
Bundle 離線、數據預取 的優化策略上線后,部分頁面在中高端機型上逼近「直開」:?
漸進式首屏
漸進式首屏解決的是「最后一公里」的問題,因為在上了「離線包」和「數據預取」的方案后,我們發現:頁面首屏時間一定程度上還是受限于首屏接口請求耗時,該方案就是為了降低用戶側的白屏等待時長,具體從以下三個方面著手:
以接口請求配置生成的索引對接口數據進行緩存
- 當用戶首次進入時,以骨架屏占位來等待業務數據加載;
- 當用戶非首次進入時,會根據接口請求配置生成的索引在本地緩存中查找緩存數據,并完成首屏渲染,同時并行發送接口請求,待新數據返回后,觸發頁面更新,完成最終渲染;
低端機降級方案
為了用戶體驗能夠更好,在此我們嘗試了低端機降級優化方案。以直播頻道為例:
- 只對首屏 Tab 做緩存數據占位優化
- 減少了低端機上首屏渲染展示數據量
圖片渲染效果優化
漸進式首屏帶來的一個問題是界面更新時的閃動(特別是圖片占大篇幅的時候),為了優化此問題,我們將圖片從加載到出現的過程改為了漸顯過渡,一定程度上消除了圖片閃動的生硬感。?
按需渲染
渲染頁面作為首屏鏈路中的一環,不同技術棧、不同設備環境下,在頁面首屏時間中也會有不同的占比。類Weex、RN 通過前端腳本映射原生組件的技術方案,渲染路徑總結起來是:渲染前端 Virtual DOM -> 映射為 Native 指令 -> 將指令傳輸到 Native 側 -> Native 執行指令完成渲染。在前三個步驟上,較重的業務邏輯或不合理的代碼通常會帶來較長的計算、通信耗時,中低端機器上尤為明顯。通過按需渲染可以有效解決這一問題。
按需渲染主要思路是通過只渲染首屏可見視圖來最小化首屏渲染耗時。本次優化中,主要針對以下幾個場景做了按需渲染:
優化上線后,魚塘廣場頁中低端機型的首屏性能有了部分數據上的提升:
低端機上優化前端渲染階段對比:
?
Bundle 瘦身
**
Bundle 體積一方面直接影響 Bundle 下載時間,另一方面也會影響 Android 端的渲染性能(耗時隨 Bundle 體積增加 1-2ms/KB),我們在 Bundle 體積上的優化方案較為常規,包括:
總結
閑魚前端的性能優化暫時告一段落,優化過程中沉淀了較多的通用能力,像 Bundle 離線、數據預取、漸進式首屏等等,這些能力在后續會有更大的發揮空間,一些能力也會變得更加智能,譬如目前的數據預取是在 navigationStart 的時候發起的,這個時機已經比傳統的頁面加載時的時機提前了許多,但其實還可以更加提前,譬如可以在閑魚客戶端中常駐個 TaskSchedule,專門用來處理數據預取的 Task,同時可以結合用戶的訪問習慣做智能數據預取。
在前端性能要求越來越高的背景下,傳統的 Web 加載流程已無法再滿足性能優化的需要,所以出現了各種新興容器 + 配套能力,所以下一代容器的標準形態應該是什么樣的?
原文鏈接:https://developer.aliyun.com/article/776157?
版權聲明:本文內容由阿里云實名注冊用戶自發貢獻,版權歸原作者所有,阿里云開發者社區不擁有其著作權,亦不承擔相應法律責任。具體規則請查看《阿里云開發者社區用戶服務協議》和《阿里云開發者社區知識產權保護指引》。如果您發現本社區中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社區將立刻刪除涉嫌侵權內容。總結
以上是生活随笔為你收集整理的从“等等”到“秒开”再到“直开”,是什么让闲鱼社区相见恨晚?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件开发必修课:你该知道的GRASP职责
- 下一篇: 蚂蚁王旭:开源协作如何提升业界的安全?