轉(zhuǎn)轉(zhuǎn)B端項目頁面性能統(tǒng)計實踐
背景
由于轉(zhuǎn)轉(zhuǎn)前端業(yè)務方向主要偏向于 C 端,比如 App端內(nèi) H5、 小程序內(nèi) H5 等,并且技術棧以 Hybrid 為主(承載容器為轉(zhuǎn)轉(zhuǎn)標準化webview)。但是,近些年隨著業(yè)務不斷擴大,逐漸出現(xiàn)了如乾數(shù)據(jù)平臺、行星平臺等 專門服務 B 端的FE項目。但是沒有相關性能數(shù)據(jù)來作為參考支撐,比如需要分析用戶體驗質(zhì)量;分析現(xiàn)有頁面性能缺陷以及后續(xù)需要做性能優(yōu)化的方向等。因此,需要一款符合轉(zhuǎn)轉(zhuǎn)內(nèi)部埋點上報體系的 PC 端項目網(wǎng)頁的性能統(tǒng)計平臺。
B 端性能統(tǒng)計面臨的問題
由于內(nèi)部性能埋點統(tǒng)計體系不支持分批/分段上報,每個 Router 都需要作為一個單獨的頁面進行一次性的性能數(shù)據(jù)上報。在 B 端,一些新的指標需要支持和特殊處理。因此,在數(shù)據(jù)采集統(tǒng)計方面,我們會遇到以下幾個問題。
- SPA Router 問題 轉(zhuǎn)轉(zhuǎn)內(nèi)部 C 端項目主要采用 hybrid 技術棧,因此不需要對 SPA 項目路由做特殊處理(因為每次都開啟一個 webview,類似于多頁面應用應用場景)。但是,基于 React 技術棧的 B 端項目是 SPA 項目,為了方便統(tǒng)計每個 Router 頁面的性能數(shù)據(jù),我們需要對每個 Router 頁面的加載進行一些特殊處理。
- SPA 資源統(tǒng)計問題 現(xiàn)在的前端 SPA 項目一般都會通過異步加載頁面資源的方式,進行頁面打包體積的優(yōu)化,以提升頁面首屏性能。因此,在進行資源統(tǒng)計時,我們需要單獨對相應的 Router 頁面的加載資源進行統(tǒng)計處理。
- B 端指標定義問題 轉(zhuǎn)轉(zhuǎn) B 端性能統(tǒng)計主要參考核心指標:白屏、首屏、完全加載。頁面性能分數(shù)評估也主要基于這三個指標進行加權計算。但是,在 Router 頁面加載時,我們會遇到核心性能指標無法直接獲取的問題,因為 Router 切換并不會產(chǎn)生頁面的 load,而只是 div 的顯示隱藏。當然了,還需要其他 B 端特有的業(yè)務標識定義,這里不一一列舉。
主要內(nèi)容
1. 性能指標定義
定義好哪些性能指標需要上報,是做好一個完善的采集性能數(shù)據(jù)采集 sdk 的前提條件,經(jīng)過分析主要將指標分為兩類:1. 純 H5 頁面性能指標 2. 頁面相關業(yè)務性指標。
- 純 H5 頁面性能指標
- 性能核心指標主要包括:白屏時間 、 首屏時間、 頁面完全加載時間,以及新增的用戶體驗指標 LCP、 FID、 CLS 。
- 輔助性性能指標包括:DNS 解析 、請求響應時間、 DOM開始構建時間、 頁面可交互時間、 DOM構建完成時間、 網(wǎng)絡速度、 各類靜態(tài)資源耗時、 ajax請求耗時、 LongTask 等等。
以上提到的絕大部分指標,可以通過瀏覽器提供的 PerformanceNavigationTiming PerformanceResourceTiming API 和 谷歌團隊提供的 web-vitals 工具函數(shù)很方便的進行獲取和計算。
- 業(yè)務性相關指標:
所謂業(yè)務性指標,主要是作為查詢分析的一些要素,比如 我們想查詢某個業(yè)務線的某個項目的某個頁面在某個平臺下某個性能指標的表現(xiàn)如何?那么就需要一些非頁面性能本身的業(yè)務要素指標進行定義和上報統(tǒng)計。
業(yè)務指標主要包括:actiontype 埋點類型標識 、 pagetype 業(yè)務線/項目標識、pageid 頁面標識 、 clientType 端信息、 pagestate 頁面狀態(tài)、pageurl 頁面url、 cookieid 用戶id、 fromType 來源、 loadcnt 加載次數(shù) 等等。
PS: web-vitals 由于在蘋果和低版本安卓的兼容性存在問題,因此沒有在 C 端作為一個必選項,但 B 端用戶絕大多數(shù)使用 chromium 內(nèi)核瀏覽器,所以大膽的將 web-vitals 納入采集指標中
2. 指標數(shù)據(jù)的獲取與上報
上面進行了各種指標的定義,那么如何高效有序的接入到轉(zhuǎn)轉(zhuǎn)埋點體系內(nèi)進行上報統(tǒng)計呢?轉(zhuǎn)轉(zhuǎn)內(nèi)部其實已經(jīng)有了 C 端埋點體系,其實只需要按照一定的規(guī)則進行接入即可,主要是性能平臺B端項目需要的字段和后端已有日志表結(jié)構做好關系映射和擴展。
為了解決上面提到B端項目的特有問題,以及滿足上述提到所有性能指標、業(yè)務指標都可以很優(yōu)雅的進行上報統(tǒng)計,方便在代碼層面更好的進行結(jié)構上的解耦,并且盡量做到性能計算統(tǒng)計相關程序不影響頁面本身的性能,在技術實現(xiàn)設計層我們把上面的指標做了一些分類,比如 同步計算指標(基礎業(yè)務同步指標、基礎性能資源同步指標)、異步計算指標(性能異步指標、后置異步指標)等。具體如下圖所示。

技術層面指標分類
下面詳細介紹一下一些關鍵邏輯是怎么處理的?各類性能指標具體是怎么計算的?下面列出了部分指標怎么獲取和計算的關鍵代碼。
SPA 項目的路由頁面的攔截關鍵邏輯:
性能基礎指標的獲取相關代碼:
資源相關指標的數(shù)據(jù)獲取關鍵邏輯:
業(yè)務指標數(shù)據(jù)的獲取:
longTask 的記錄獲?。?/p>
在實際項目統(tǒng)計時,發(fā)現(xiàn)一些性能指標算法的適用性問題需要注意:
- LCP 算法存在的問題。比如:觸發(fā)條件限制的問題,當檢測到用戶輸入時候 FMP算法會停止計算,就導致某些場景觸發(fā)不了(比如主要內(nèi)容還沒顯示就點擊頁面)。白屏占位圖問題,頁面初始有較大的白屏占位圖時 即使后面被移除了,LCP 算法還會把它當作主要內(nèi)容。
- FMP 算法不適合某些特殊場景。比如:2/3 是金剛位圖片布局,最下面 1/3 區(qū)域有一個瀑布流,由于FMP算法計算規(guī)則會導致統(tǒng)計時間在瀑布流請求之后展現(xiàn)后,就導致直觀上的頁面首屏時間變大。
數(shù)據(jù)可以計算并獲取了,那么如何進行友好的處理上報?
由于內(nèi)部埋點提下不支持回話形式的分段上報,那么就需要在前端提前準備好所有需要需要上報的數(shù)據(jù)的處理,整體B端 SPA 項目性能數(shù)據(jù)處理的上報處理機制,以及同步任務數(shù)據(jù)、異步任務數(shù)據(jù)任務的處理流如下圖所示。

3. 上報數(shù)據(jù)的體積優(yōu)化
在進行數(shù)據(jù)上報時,如果頁面的靜態(tài)資源加載 / ajax請求數(shù)量很多時,埋點上報請求接口的 body 會很大,導致請求耗時長而影響頁面本身的性能。因此針對 body 過大的問題,對一些資源的統(tǒng)計做了序列化處理。
比如:單條靜態(tài)資源的原始數(shù)據(jù)結(jié)構為:
序列化之后,將各個關鍵數(shù)據(jù)合并成一個字符串,即:
可以發(fā)現(xiàn)系列化精簡后將 255個字符優(yōu)化成了 42 個字符。
往往B端 SPA 項目靜態(tài)資源和請求多達幾十上百個,這樣序列化處理合并之后,能將埋點上報請求 body 體積減少數(shù)千個字節(jié)。當然了,如果服務支持編解碼,還可以通過其他更優(yōu)的序列化方案進行 body 體積壓縮。
4. 數(shù)據(jù)存儲與處理
在對數(shù)據(jù)進行處理時,也遇到了一些問題。
每天上報的性能埋點數(shù)據(jù)存儲在哪里?
如何計算數(shù)據(jù)?如何擴展數(shù)據(jù)?如何查詢數(shù)據(jù)?
二次計算后的數(shù)據(jù)量依舊非常大,該怎么辦?
- 原始性能數(shù)據(jù)通過SDK采集后,經(jīng)過數(shù)據(jù)倉庫的清洗,存儲在Hadoop中。雖然Hadoop可以存儲PB級別的數(shù)據(jù),但查詢速度較慢,不適合實時性能分析查詢。為了解決這個問題,我們嘗試將清洗后的數(shù)據(jù)復制一份存儲在MySQL中,但隨著數(shù)據(jù)量的增加,MySQL方案出現(xiàn)了許多問題。考慮到實際場景的并發(fā)量不會太高,我們最終選擇將明細數(shù)據(jù)存儲在ClickHouse中。
- 雖然明細數(shù)據(jù)可以通過查詢ClickHouse獲取,但對于許多聚合計算得出的數(shù)據(jù),如果仍然通過查詢并實時計算,效率并不理想。因此,在數(shù)據(jù)落庫后,我們通過定時任務預先計算一部分聚合數(shù)據(jù),然后將其導入MySQL中。這種做法的好處在于,這部分預先計算好的數(shù)據(jù)可以進行查詢,用戶體驗更好,而且后續(xù)需要擴展時,只需要對聚合數(shù)據(jù)進行二次計算加工即可。目前,聚合數(shù)據(jù)使用了6個維度進行分組計算,這些維度也可以用于組合查詢,方便后續(xù)擴展。
- 盡管聚合數(shù)據(jù)已經(jīng)合并計算過,但由于多維度組合,數(shù)據(jù)量仍然非常龐大。隨著后續(xù)維度的擴展,整體數(shù)據(jù)量呈指數(shù)級增長。考慮到性能分析的周期性不會太長,我們決定只保留整體聚合數(shù)據(jù)7天,并進行分表處理。如果數(shù)據(jù)量激增,我們會采取將數(shù)據(jù)轉(zhuǎn)入TiDB中,并按日期進行分區(qū)存儲。
為了解決數(shù)據(jù)處理中的兩個核心問題,我們采用了這個完整的流程。在面對如此龐大的數(shù)據(jù)時,我們需要考慮它們存儲在何處。同時,我們也需要考慮如何查找和計算需要的指標。這個流程可以幫助我們更好地處理數(shù)據(jù),提高效率。
此外,這個流程還有一個重要的作用,那就是保證數(shù)據(jù)的準確性和完整性。在數(shù)據(jù)處理過程中,我們需要遵循一定的規(guī)則和標準,以確保數(shù)據(jù)的可靠性。這樣才能讓我們在分析數(shù)據(jù)時得出正確的結(jié)論,更好的進行針對性的優(yōu)化。
5. 性能查詢展示平臺
web平臺部分功能頁面展示如下:

歷史變化曲線

性能數(shù)據(jù)查詢
總結(jié)
在B端項目中,頁面性能統(tǒng)計是非常有必要的,因為可以幫助我們了解實際用戶的具體頁面的加載速度、用戶體驗,以便了解當前頁面的質(zhì)量,并且為優(yōu)化頁面性能提供方向,從而提高用戶滿意度。





































