搭建自動化 Web 頁面性能檢測系統(tǒng) —— 設(shè)計篇

頁面性能對于用戶體驗、用戶留存有著重要影響,當(dāng)頁面加載時間過長時,往往會伴隨著一部分用戶的流失,也會帶來一些用戶差評。性能的優(yōu)劣往往是同類產(chǎn)品中勝出的影響因素,也是一個網(wǎng)站口碑的重要評判標(biāo)準(zhǔn)。

一、名稱解釋

前端監(jiān)控一般分為合成監(jiān)控和真實用戶監(jiān)控。

1.1、合成監(jiān)控

合成監(jiān)控就是模擬用戶的使用場景,訪問一個頁面,通過一些工具和規(guī)則去檢測頁面,提取一些性能指標(biāo),生成一份檢測報告,注重檢測。

合成監(jiān)控的優(yōu)缺點:

優(yōu)點 缺點
實現(xiàn)簡單,社區(qū)方案成熟 配置復(fù)雜,不能完全還原用戶真實場景
能采集到更豐富的數(shù)據(jù) 登錄等場景需要單獨處理
不影響真實用戶的頁面訪問性能 單次檢測數(shù)據(jù)不夠準(zhǔn)確

1.2、真實用戶監(jiān)控

image.png

真實用戶監(jiān)控是指用戶在頁面上訪問,訪問時會產(chǎn)生各類性能數(shù)據(jù),在用戶訪問停止的時候,將這些性能數(shù)據(jù)傳輸?shù)椒?wù)端,進行數(shù)據(jù)整理分析的過程,注重監(jiān)控。

真實用戶監(jiān)控的優(yōu)缺點:

優(yōu)點 缺點
完全還原用戶真實場景 對用戶的訪問性能有一定影響
登錄等場景無需單獨解決 無法采集完整的資源加載瀑布圖
數(shù)據(jù)樣本足夠大且真實,數(shù)據(jù)價值高 無法可視化展示頁面加載過程

1.3、定義合適的性能指標(biāo)

  1. 首次內(nèi)容渲染時長(First Contentful Paint, FCP)
    頁面最新出現(xiàn)的內(nèi)容渲染時長
  2. 首次展現(xiàn)平均值(Speed Index, SI)
    頁面內(nèi)容可見填充的速度
  3. 最大內(nèi)容繪制時間(Largest Contentful Paint, LCP)
    頁面核心內(nèi)容呈現(xiàn)時間,不采用 loading 狀態(tài)的數(shù)據(jù)
  4. 可交互時間(Time to Interactive, TTI)
    用戶是否會體驗到卡頓
  5. 總阻塞時間(Total Blocking Time, TBT)
    主線程被阻塞的時間,無法作出輸入響應(yīng)
  6. 累計布局樣式偏移(Cumulative Layout Shift, CLS)
image.png

二、為什么做

基于需要對公司的 Web 產(chǎn)品進行性能優(yōu)化,在做性能優(yōu)化的同時,優(yōu)化的衡量標(biāo)準(zhǔn)也不可或缺。在頁面開發(fā)時觀察頁面的性能并不夠準(zhǔn)確,因為不同的開發(fā)設(shè)備性能表現(xiàn)不同,所伴隨的變量也較多,不能夠準(zhǔn)確的反映性能優(yōu)化效果,也無法觀察產(chǎn)品的性能變化趨勢。為什么自研呢,自研有以下好處:

(1)借助第三方的性能檢測服務(wù)往往不能保證檢測數(shù)據(jù)的安全性。

(2)第三方的性能檢測服務(wù)一般無法與公司內(nèi)部系統(tǒng)打通流程,一般無法自動化檢測公司內(nèi)部產(chǎn)品。

(3)可以做一些自定義開發(fā),比如根據(jù)產(chǎn)品特點調(diào)整不同的性能指標(biāo)權(quán)重,從而更準(zhǔn)確的計算分?jǐn)?shù)。

那么在檢測收集到了這么多的指標(biāo)數(shù)據(jù)后,頁面性能到底如何呢,如果你的老板問你公司的產(chǎn)品頁面性能如何,你該如何回復(fù)呢?假設(shè)列舉一大堆時間指標(biāo)、偏移量等數(shù)據(jù),老板看到這些數(shù)值的時候可能就是一頭霧水,根本理解不了產(chǎn)品的頁面性能到底如何。那么自研可以針對產(chǎn)品類型,給出一個統(tǒng)一的標(biāo)準(zhǔn),這樣就方便去對比各個產(chǎn)品的性能表現(xiàn)了。

三、怎么做

3.1、基礎(chǔ)依賴

下面是檢測系統(tǒng)的整體架構(gòu):

image.png

這里設(shè)計的性能檢測系統(tǒng)主要包含前端頁面和服務(wù)端,其中:

前端頁面展示性能檢測入口、檢測結(jié)果、性能趨勢、性能排行榜等。

服務(wù)端基于 Nestjs + Lighthouse + Puppeteer 實現(xiàn),通過 Typeorm 操作 MySQL 數(shù)據(jù)庫,記錄和查詢性能檢測數(shù)據(jù)。

另外輔助一些插件進行定時監(jiān)測、結(jié)果通知等操作,實現(xiàn)自動化檢測,相比頁面開發(fā)時通過開發(fā)者工具中的 Lighthouse 檢測有以下好處:

(1)不用開發(fā)者主動觸發(fā);

(2)不會阻塞開發(fā)過程,無需等待;

Lighthouse 用于檢測 Web 網(wǎng)頁的性能,主要基于 4 個主要步驟實現(xiàn),分別是交互驅(qū)動、性能數(shù)據(jù)收集、審計整理以及記錄。具體為:

(1)用戶在性能檢測入口輸入待檢測的頁面地址,點擊開始檢測,頁面通過接口調(diào)用性能檢測服務(wù)

(2)Lighthouse 遍歷當(dāng)前頁面的收集器方法并合成一個總的收集器方法以便于采集數(shù)據(jù)

(3)對上述采集到的性能數(shù)據(jù)進行計算和評分

Lighthouse 主要提供六個收集器,通過以下六個收集器即可采集到和實際訪問接近的性能數(shù)據(jù),每個收集器的功能不一,如下:

(1)收集 DOM 元素相關(guān)數(shù)據(jù)、DOM 節(jié)點最大深度、滾動條等

(2)收集頁面內(nèi)的所有圖片資源,并記錄下每個圖片元素的寬高和定位等屬性

(3)收集相關(guān)指標(biāo),如:FCP、LCP、CLS 等

(4)收集 JS 事件監(jiān)聽數(shù)量、JS 堆棧等

(5)收集頁面的所有請求,包括狀態(tài)碼、請求頭、響應(yīng)頭、請求方式等

(6)收集 window.performance 下的性能數(shù)據(jù),用于計算加載時間

Puppeteer 是 Chrome 團隊提供的一個無界面 Chrome 工具,俗稱無頭瀏覽器,通過提供的 API 可以控制 Node 端的 Chrome 工具進行指定的操作。在這里設(shè)計的性能檢測系統(tǒng)中,由于 Lighthouse 進行檢測時打開的類似于無痕窗口,沒有登錄信息,所以 Puppeteer 主要幫助我們實現(xiàn)模擬登錄。

當(dāng)檢測頁面需要登錄時,分析出頁面屬于哪個 devops 實例,然后通過 Puppeteer 跳轉(zhuǎn)到對應(yīng)的登錄頁面,然后輸入用戶名、密碼、驗證碼,待登錄完成后跳轉(zhuǎn)至正確的頁面,再進行頁面性能檢測。如果登錄后還在登錄頁,表示登錄失敗,則獲取錯誤提示并拋出。

以下是檢測系統(tǒng)的一個流程圖:

image.png

3.2、關(guān)鍵代碼

// 開始檢測
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);

        // 保存檢測結(jié)果文件,便于預(yù)覽
        const urlStr = url.replace(/http(s?):\/\//g, '').replace(/\//g, '');
        fs.writeFileSync(`./static/${urlStr}-report.html`, runResult?.report);

        // 性能數(shù)據(jù)
        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,
        };
    }
}

3.3、檢測規(guī)則

系統(tǒng)除了支持手動輸入網(wǎng)頁地址檢測,也支持自動檢測。為了便于統(tǒng)計每個子產(chǎn)品的真實表現(xiàn),每天凌晨自動檢測 10 次,去掉最高分,去掉最低分,從其余分?jǐn)?shù)中選擇中位數(shù)作為每天的檢測評分。

性能檢測時的數(shù)據(jù)采集可能因為網(wǎng)頁服務(wù)的不穩(wěn)定性,導(dǎo)致有偏大或偏小的數(shù)據(jù),所以提供某個時間段某個指標(biāo)的直方圖來分析數(shù)據(jù)的基本特征。也會提供某個產(chǎn)品的整體分?jǐn)?shù)趨勢,便于統(tǒng)計某個時間段內(nèi)該產(chǎn)品的性能變化,也可以提現(xiàn)性能優(yōu)化前后的效果。

image.png

四、寫在后面

這篇文章簡單介紹了下該性能檢測系統(tǒng)的初步設(shè)計、一些頁面性能的概念以及采用的技術(shù)點,后續(xù)請關(guān)注《搭建自動化 Web 頁面性能檢測系統(tǒng) —— 實踐篇》。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容