我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式資料中臺產品。我們始終保持工匠精神,探索前端道路,為社群積累並傳播經驗價值。。
本文作者:琉易 liuxianyu.cn
頁面效能對於使用者體驗、使用者留存有著重要影響,當頁面載入時間過長時,往往會伴隨著一部分使用者的流失,也會帶來一些使用者差評。效能的優劣往往是同類產品中勝出的影響因素,也是一個網站口碑的重要評判標準。
前端監控一般分為合成監控和真實使用者監控。
合成監控就是模擬使用者的使用場景,存取一個頁面,通過一些工具和規則去檢測頁面,提取一些效能指標,生成一份檢測報告,注重檢測。
合成監控的優缺點:
優點 | 缺點 |
---|---|
實現簡單,社群方案成熟 | 設定複雜,不能完全還原使用者真實場景 |
能採集到更豐富的資料 | 登入等場景需要單獨處理 |
不影響真實使用者的頁面存取效能 | 單次檢測資料不夠準確 |
真實使用者監控是指使用者在頁面上存取,存取時會產生各類效能資料,在使用者存取停止的時候,將這些效能資料傳輸到伺服器端,進行資料整理分析的過程,注重監控。
真實使用者監控的優缺點:
優點 | 缺點 |
---|---|
完全還原使用者真實場景 | 對使用者的存取效能有一定影響 |
登入等場景無需單獨解決 | 無法採集完整的資源載入瀑布圖 |
資料樣本足夠大且真實,資料價值高 | 無法視覺化展示頁面載入過程 |
基於需要對公司的 Web 產品進行效能優化,在做效能優化的同時,優化的衡量標準也不可或缺。在頁面開發時觀察頁面的效能並不夠準確,因為不同的開發裝置效能表現不同,所伴隨的變數也較多,不能夠準確的反映效能優化效果,也無法觀察產品的效能變化趨勢。為什麼自研呢,自研有以下好處:
(1)藉助第三方的效能檢測服務往往不能保證檢測資料的安全性。
(2)第三方的效能檢測服務一般無法與公司內部系統打通流程,一般無法自動化檢測公司內部產品。
(3)可以做一些自定義開發,比如根據產品特點調整不同的效能指標權重,從而更準確的計算分數。
那麼在檢測收集到了這麼多的指標資料後,頁面效能到底如何呢,如果你的老闆問你公司的產品頁面效能如何,你該如何回覆呢?假設列舉一大堆時間指標、偏移量等資料,老闆看到這些數值的時候可能就是一頭霧水,根本理解不了產品的頁面效能到底如何。那麼自研可以針對產品型別,給出一個統一的標準,這樣就方便去對比各個產品的效能表現了。
下面是檢測系統的整體架構:
這裡設計的效能檢測系統主要包含前端頁面和伺服器端,其中:
前端頁面展示效能檢測入口、檢測結果、效能趨勢、效能排行榜等。
伺服器端基於 Nestjs + Lighthouse + Puppeteer 實現,通過 Typeorm 操作 MySQL 資料庫,記錄和查詢效能檢測資料。
另外輔助一些外掛進行定時監測、結果通知等操作,實現自動化檢測,相比頁面開發時通過開發者工具中的 Lighthouse 檢測有以下好處:
(1)不用開發者主動觸發;
(2)不會阻塞開發過程,無需等待;
Lighthouse 用於檢測 Web 網頁的效能,主要基於 4 個主要步驟實現,分別是互動驅動、效能資料收集、審計整理以及記錄。具體為:
(1)使用者在效能檢測入口輸入待檢測的頁面地址,點選開始檢測,頁面通過介面呼叫效能檢測服務
(2)Lighthouse 遍歷當前頁面的收集器方法併合成一個總的收集器方法以便於採集資料
(3)對上述採集到的效能資料進行計算和評分
Lighthouse 主要提供六個收集器,通過以下六個收集器即可採集到和實際存取接近的效能資料,每個收集器的功能不一,如下:
(1)收集 DOM 元素相關資料、DOM 節點最大深度、卷軸等
(2)收集頁面內的所有圖片資源,並記錄下每個圖片元素的寬高和定位等屬性
(3)收集相關指標,如:FCP、LCP、CLS 等
(4)收集 JS 事件監聽數量、JS 堆疊等
(5)收集頁面的所有請求,包括狀態碼、請求頭、響應頭、請求方式等
(6)收集 window.performance 下的效能資料,用於計算載入時間
Puppeteer 是 Chrome 團隊提供的一個無介面 Chrome 工具,俗稱無頭瀏覽器,通過提供的 API 可以控制 Node 端的 Chrome 工具進行指定的操作。在這裡設計的效能檢測系統中,由於 Lighthouse 進行檢測時開啟的類似於無痕視窗,沒有登入資訊,所以 Puppeteer 主要幫助我們實現模擬登入。
當檢測頁面需要登入時,分析出頁面屬於哪個 devops 範例,然後通過 Puppeteer 跳轉到對應的登入頁面,然後輸入使用者名稱、密碼、驗證碼,待登入完成後跳轉至正確的頁面,再進行頁面效能檢測。如果登入後還在登入頁,表示登入失敗,則獲取錯誤提示並丟擲。
以下是檢測系統的一個流程圖:
// 開始檢測
async run(urlDto: UrlDto): Promise<object> {
const start = new Date().getTime();
try {
const { url, loginUrl } = urlDto;
const needLogin = url.includes('devops') || loginUrl;
console.log(`本次檢測${needLogin ? '' : '不'}需要登入`, url);
const runResult = needLogin
? await this.withLogin(urlDto)
: await this.withOutLogin(url);
// 儲存檢測結果檔案,便於預覽
const urlStr = url.replace(/http(s?):\/\//g, '').replace(/\//g, '');
fs.writeFileSync(`./static/${urlStr}-report.html`, runResult?.report);
// 效能資料
const performance = runResult?.lhr?.categories?.performance || {};
const data = {
...performance,
auditRefs: performance?.auditRefs?.filter((item) => item.weight),
};
// console.log(data);
console.log(`本次耗時:${((new Date().getTime() - start) / 1000).toFixed(2)}s`);
return {
code: 200,
data,
message: `耗時:${((new Date().getTime() - start) / 1000).toFixed(2)}s`,
};
} catch (error) {
return {
code: 401,
message: error,
};
}
}
系統除了支援手動輸入網頁地址檢測,也支援自動檢測。為了便於統計每個子產品的真實表現,每天凌晨自動檢測 10 次,去掉最高分,去掉最低分,從其餘分數中選擇中位數作為每天的檢測評分。
效能檢測時的資料採集可能因為網頁服務的不穩定性,導致有偏大或偏小的資料,所以提供某個時間段某個指標的直方圖來分析資料的基本特徵。也會提供某個產品的整體分數趨勢,便於統計某個時間段內該產品的效能變化,也可以提現效能優化前後的效果。
這篇文章簡單介紹了下該效能檢測系統的初步設計、一些頁面效能的概念以及採用的技術點,後續請關注《搭建自動化 Web 頁面效能檢測系統 —— 實踐篇》。
歡迎關注【袋鼠雲數棧UED團隊】~
袋鼠雲數棧UED團隊持續為廣大開發者分享技術成果,相繼參與開源了歡迎star