博客 / 詳情

返回

秒開率破90%!交易後台渲染性能優化 | 得物技術

前言

一直以來,體驗都是得物技術部的關鍵詞之一,對於前端開發而言,提高用户體驗更是一項至關重要的工作。本文從本次交易後台性能優化實踐出發,同時介紹應用整體架構和設計,希望可以給參與網站性能建設的同學提供一定的學習和參考價值。

系統簡介

交易後台是現有交易流程主要系統,包含商品、出價、商家、訂單等二級業務域,其承載了交易的核心任務,在交易平台的整體架構中佔據着非常重要的地位。業務背景:整體日均 PV 數達到 10w+,其中 SPU 場景佔比超過一半,由於頁面功能結構複雜的原因,運營的使用體驗和交易效率有一定程度上的影響。技術背景:應用基於 qiankun 微前端架構,首屏加載資源過多,包括主子應用 JS 和樣式文件,圖片和其他靜態資源,數十個子應用路由信息和數百個菜單項,以及接入的一些三方 SDK 等。

性能現狀

先看優化前的首屏效果(沒有開慢倍速):
圖片
可以從動圖看出頁面加載速度、白屏時間都不太理想,顯然和我們的目標首屏秒開還有一段距離,為了實現首屏秒開的目標,可以先從以下幾個方面進行分析。

性能看板分析

Chrome Performance 火焰圖在頁面性能問題分析中是一項非常重要的工具。

相關閲讀:https://juejin.cn/post/6844904074551230471

圖片
在打開看板後,先關注下這幾個紅色區域長任務,我們知道主線程一次只能處理一個任務,所以這會導致瀏覽器在主線程上阻塞一段時間,也是造成頁面卡頓的主要原因。看下底部調用樹的情況:Task1: 發生在 DCL 之前,因為瀏覽器解析 HTML 文件時,會在遇到<script>標籤時立即執行腳本文件,所以 webpack_require 和 Compile Code 很可能是因為入口文件過大導致。
圖片
Task2: 發生在 FCP 之後,主要是源碼中組件渲染相關的核心函數,componentUpdateFn 用於比較新舊 VNode 的差異,並調用 patch 函數對真實 DOM 進行更新,所以初步判斷是渲染複雜組件導致。
圖片
另外可以觀察以下關鍵性能指標,瞭解一下頁面加載的各個階段的耗時情況

  • First Contentful Paint(FCP):首次內容繪製時間,此時頁面僅展示出一些水印組件,和白屏幾乎沒區別,一般應該在頁面加載後的 1-2s 內完成,此時用户可以感受到頁面正在加載。(當前耗時2s+)
  • Largest Contentful Paint(LCP):最大內容繪製時間,此時主應用框架渲染基本完成,子應用還未開始加載。通常應該在頁面加載後的 2.5s 內完成,否則用户可能會感到頁面加載緩慢。(當前耗時4s+)

根據這些具體的性能指標,之後才能更好的度量優化效果。

渲染流程分析

為了快速定位問題,我們按步驟拆分一下頁面整體加載的渲染流程,這有助於我們做出針對性的優化。
圖片
我們重點關注幾個標記的部分,接下來就可以根據實際情況逐一擊破了。

方案拆解

根據對應用渲染流程的分析,我們可以將整體優化方案作進一步的拆解,並設置對應動作的開發優先級。

圖片

並通過二八法則,我們將主要精力重點投入到高優方案中,確保整體性能的提升。

具體動作

首屏資源優化

首屏資源加載會直接影響頁面的渲染速度和體驗,我們先查看下首屏資源的加載情況,由於各類資源請求過多,這裏僅過濾來源於主應用的網絡請求。可以直接從中發現幾個可優化的點:

  • 入口 JS 資源文件 Size 優化

    • 嚴重影響了頁面整體加載性能,可以通過構建體積優化,主要思路就是代碼分割拆包,靜態資源上傳 CDN,腳本代碼壓縮等方式處理
  • 接口緩存、調用時序治理

    • 針對用户信息、菜單信息等不常變動的接口可以採用相關緩存策略,減少首屏等待的時間
    • 部分優先級不高的接口可以延遲調用,異步加載
    // 我們採用 Cache aside 旁路緩存策略
    async function cacheRequest(params: any) {  
        const startTime = Date.now()  
        const key = params.key  
        const cache: any = JSON.parse(localStorage.getItem(key) || '{}') 
        // 當天有緩存  
        const canCache = cache.cacheTime&&moment(cache.cacheTime).isSame(moment(startTime), 'day')
        
        window.sendTrack?.({    
    event: 'main_request_cache',    
    tags: {      
     eventTitle: '主應用數據緩存',      
     eventType: canCache ? 1 : 0,    
        },  
      })
        
      const requestCache = async () => {    
        const data = await request(params)    
        localStorage.setItem(key, JSON.stringify({      
      data,      
      cacheTime: Date.now()    
    }))    
    return data  
      }  
      // 優先從緩存中讀取數據 後續再更新緩存 保證數據的一致性  
      if (canCache) {    
        setTimeout(requestCache, DELAY_CACHE_TIME * 1000)    
        return cache.data  
      } else {    
        const data = await requestCache()    
        return data  
      }
    }
  • 三方 SDK 集中治理

    • 儘量放在 script 標籤中異步加載腳本,可以加快解析時間且保證主入口文件的加載不會被阻塞
    • 另外注意防止子應用重複加載,還有部分 SDK 需要及時下線

其實原則只有一個:減少首屏需要加載的資源數量和大小,並儘快加載必要的資源。

渲染優先級優化

最後為了減少 LCP 的等待時間,我們將頁面左側菜單欄做一個懶加載處理,初始化僅展示一級目錄菜單,既考慮了首屏視覺效果,也間接將子應用加載的時間點提前。

相關閲讀:當不希望因為不重要的任務導致用户感覺到卡頓的話,就應該考慮使用requestIdleCallback:https://juejin.cn/post/6844903592831238157

// 採用 requestIdleCallback 方式利用 CPU 空閒時間漸進地加載內容
try {    
    requestIdleCallback((deadline) => {        
        // 當前幀有剩餘時間 可以執行任務        
        while (deadline.timeRemaining() > 0 && || deadline.didTimeout) {            
           // 加載剩餘部分菜單項        
        }    
    })  
  } catch (e) {    
    // 低版本瀏覽器兜底處理    
    setTimeout(() => {      
     // 加載剩餘部分菜單項    
    }, DELAY_LOAD_TIME) 
  }
}

最後再看下優化後的首屏效果(沒有開快倍速):
圖片

效果回收

主要性能指標

優化後各項指標數據均有一定提升,其中

秒開率(首次打開頁面<1秒佔比,以 FMP 為準):🔝15%+

頁面首次進入FMP90分位均值(秒):🔝35%+

頁面TTI%(可交互時長<1.5s佔比) :🔝30%+

TTI 90分位均值(秒):🔝50%+

上述數據均來源於效率工程應用系統前端大盤看板。

圖片
優化前-7月
圖片
優化後-9月
其他相關數據統計(本機測試):頁面傳輸資源大小減少約 1M、頁面資源加載時間下降超過 0.5s、FCP、LCP 也分別優化到 1s、2s 以內 ,整體結果超出預期

七、總結展望

隨着業務複雜度提升和用户規模的增加,系統的性能和效率必然會面臨更多的挑戰,本輪性能優化工作基本告一段落,雖然取得了一些成績,但還有很多事項需要後續不斷的完善,比如:

  1. 框架層面優化。深入探究微前端框架層的性能瓶頸,降低應用間消息傳遞通信和模塊重複資源加載損耗
  2. 使用 Service Worker。執行一些計算密集型或網絡請求相關的任務,實現靜態資源緩存優化
  3. 資源加載優化。利用發佈平台事件同步能力實現應用配置文件按需加載,避免網絡帶寬造成過大的壓力

希望能通過各項措施逐步形成後台應用性能優化最佳實踐,從而避免各種性能卡點問題,進一步保證運營體驗。

*文/ Johnny

本文屬得物技術原創,更多精彩文章請看:得物技術官網

未經得物技術許可嚴禁轉載,否則依法追究法律責任!

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.