一文完全搞懂前端監控

關注公衆號「執鳶者」,回覆「紅寶書」獲取「javaScript高級程序第四版(pdf)」及大量前端學習資料。

1、前端監控現狀

近年來,前端監控是愈來愈火,目前已經有不少成熟的產品供咱們選擇使用,以下圖所示

有這麼多監控平臺,那爲何還要學習搞前端監控?css

  • 一方面人家是要錢的
  • 另外一方面本身的項目須要定製化的功能。

2、前端監控的目的

  1. 提高用戶體驗
  2. 更快的發現發現異常、定位異常、解決異常
  3. 瞭解業務數據,指導產品升級——數據驅動的思想

3、前端監控的流程

3.1 採集

前端監控的第一個步驟就是數據採集,採集的信息包含環境信息、性能信息、異常信息、業務信息。

3.1.1 環境信息

環境信息是每一個監控系統必備的內容,畢竟排查問題的時候須要知道來自哪一個頁面、瀏覽器是誰、操做用戶是誰……,這樣才能快速定位問題,解決問題。通常這些常見的環境信息主要包含:
  1. url:正在監控的頁面,該頁面可能會出現性能、異常問題。獲取方式爲:<br/>
    window.location.href<br/>
  2. ua:訪問該頁面時該用戶的userAgent信息,包含操做系統和瀏覽器的類型、版本等。獲取方式爲:<br/>
    window.navigator.userAgent
  3. token:記錄當前用戶是誰。經過記錄該用戶是誰。<br/>
    一方面方便將該用戶的全部監控信息創建聯繫,方便數據分析;<br/>
    另外一方面經過該標識能夠查看該用戶的全部操做,方便復現問題。<br/>

3.1.2 性能信息

頁面的性能直接影響了用戶留存率,,Google DoubleClick 研究代表:若是一個移動端頁面加載時長超過 3 秒,用戶就會放棄而離開。BBC 發現網頁加載時長每增長 1 秒,用戶就會流失 10%。,Google DoubleClick 研究代表:若是一個移動端頁面加載時長超過 3 秒,用戶就會放棄而離開。BBC 發現網頁加載時長每增長 1 秒,用戶就會流失 10%。因此咱們的追求就是提升頁面的性能,爲了提升性能須要監控哪些指標呢?
3.1.2.1 指標分類
指標有不少,我總結爲如下兩個方面:網絡層面和頁面展現層面。
1、網絡層面
從網絡層面來看涉及的指標有:重定向耗時、DNS解析耗時、TCP鏈接耗時、SSL耗時、TTFB網絡請求耗時、數據傳輸耗時、資源加載耗時……,各個指標的解釋以下表所示:
指標 解釋
重定向耗時 重定向所耗費的時間
DNS解析耗時 瀏覽器輸入網址後首先會進行DNS解析,其能夠對服務器是否工做做出反饋
TCP鏈接耗時 指創建鏈接過程的耗時
SSL鏈接耗時 指數據安全性、完整性創建耗時
TTFB 網絡請求耗時 表示瀏覽器接收第一個字節的時間
數據傳輸耗時 瀏覽器接收內容所耗費的時間
資源加載耗時 DOM構建完畢後到頁面加載完畢這段時間

2、頁面展現層面前端

頁面展現層面的指標是針對用戶體驗提出的幾個指標,包含FP、FCP、LCP、FMP、DCL、L等,這幾個指標其實就是chrome瀏覽器中performance模塊的指標(如圖所示)。

各個指標的解釋以下表所示。java

指標 解釋
FP(First Paint) 首次繪製,標記瀏覽器渲染任何在視覺上不一樣於導航前屏幕內容以內容的時間點.
FCP(First Contentful Paint) 首次內容繪製,標記瀏覽器渲染來自 DOM 第一位內容的時間點,該內容多是文本、圖像、SVG 甚至 元素.
LCP(Largest Contentful Paint) 最大內容渲染,表示可視區「內容」最大的可見元素開始出如今屏幕上的時間點。
FMP(First Meaningful Paint) 首次有效繪製,表示頁面的「主要內容」開始出如今屏幕上的時間點。它是咱們測量用戶加載體驗的主要指標。
DCL(DomContentLoaded) 當 HTML 文檔被徹底加載和解析完成以後,DOMContentLoaded 事件被觸發,無需等待樣式表、圖像和子框架的完成加載.
L(onLoad) 當依賴的資源所有加載完畢以後纔會觸發
TTI(Time to Interactive) 可交互時間,用於標記應用已進入視覺渲染並能可靠響應用戶輸入的時間點
FID(First Input Delay) 首次輸入延遲,用戶首次和頁面交互(單擊連接、點擊按鈕等)到頁面響應交互的時間
3.1.2.2 指標求解
上述這麼多指標該怎麼獲取呢?瀏覽器給咱們留了相應的接口——神奇的window.performance,經過該接口能夠獲取一些列與性能相關的參數,下面以 https://baidu.com 爲例來看一下與這些指標相關的參數:

window.performance中的timing屬性中的內容不就是爲了求解上述指標所須要的值嗎?看着上面的屬性值再對應下面的performance訪問流程圖,整個過程是否是一目瞭然。

有了上面的值咱們就一塊兒求解上述的指標:
1、網絡層面
指標 計算
重定向耗時 redirectEnd - redirectStart
DNS解析耗時 domainLookupEnd - domainLookupStart
TCP鏈接耗時 connectEnd - connectStart
SSL鏈接耗時 connectEnd - secureConnectionStart
TTFB 網絡請求耗時 responseStart - requestStart
數據傳輸耗時 responseEnd - responseStart
資源加載耗時 loadEventStart - domContentLoadedEventEnd

2、頁面展現層面node

Google工程師一直在推進以用戶爲中心的性能指標,因此頁面展現層面的變化較大,求解方式稍有不一樣:
  1. FP和FCP

經過window.performance.getEntriesByType(‘paint’)的方式獲取chrome

const paint = window.performance.getEntriesByType('paint');
const FP = paint[0].startTime,
const FCP = paint[1].startTime,
  1. LCP
function getLCP() {
    // 增長一個性能條目的觀察者
    new PerformanceObserver((entryList, observer) => {
        let entries = entryList.getEntries();
        const lastEntry = entries[entries.length - 1];
        observer.disconnect();
        console.log('LCP', lastEntry.renderTime || lastEntry.loadTime);
    }).observe({entryTypes: ['largest-contentful-paint']});
}
  1. FMP
function getFMP() {
    let FMP;
    new PerformanceObserver((entryList, observer) => {
        let entries = entryList.getEntries();
        observer.disconnect();
        console.log('FMP', entries);
    }).observe({entryTypes: ['element']});
}
  1. DCL
domContentLoadEventEnd – fetchStart
  1. L
loadEventStart – fetchStart
  1. TTI
domInteractive – fetchStart
  1. FID
function getFID() {
    new PerformanceObserver((entryList, observer) => {
        let firstInput = entryList.getEntries()[0];
        if (firstInput) {
            const FID = firstInput.processingStart - firstInput.startTime;
            console.log('FID', FID);
        }
        observer.disconnect();
    }).observe({type: 'first-input', buffered: true});
}

3.1.3 異常信息

對於網站來講,異常信息是最致命、最影響用戶體驗的問題,須要重點監控。對於異常信息能夠分爲兩類:運行時錯誤、接口錯誤。下面就分別來嘮一嘮這兩類錯誤。

1、運行時錯誤數據庫

當JavaScript運行時有可能會發生錯誤,可歸類爲七種:語法錯誤、類型錯誤、範圍錯誤、引用錯誤、eval錯誤、URL錯誤、資源加載錯誤。爲了捕獲代碼錯誤,須要考慮兩類場景:非Promise場景和Promise場景,由於兩種場景捕獲錯誤的策略不一樣。

1.非Promise場景後端

非Promise場景可經過監聽error事件來捕獲錯誤。對於error事件捕獲的錯誤分爲兩類:資源錯誤和代碼錯誤。資源錯誤指的就是js、css、img等未加載,該錯誤只能在捕獲階段獲取到,且爲資源錯誤時event.target.localName存在值(用此區分資源錯誤與代碼錯誤);代碼錯誤指的就是語法錯誤、類型錯誤等這一類錯誤,能夠獲取代碼錯誤的信息、堆棧等,用於排查錯誤。
export function listenerError() {
    window.addEventListener('error', (event) => {
        if (event.target.localName) {
            console.log('這是資源錯誤', event);
        }
        else {
            console.log('這是代碼錯誤', event);
        }
    }, true)
}

2.Promise場景跨域

Promise場景的處理方式有所不一樣,當Promise被reject且沒有reject處理器的時候,會觸發unhandlerejection事件,因此經過監聽unhandlerejection的事件來捕獲錯誤。
export function listenerPromiseError() {
    window.addEventListener('unhandledrejection', (event) => {
        console.log('這是Promise場景中錯誤', event);
    })
}

2、接口錯誤瀏覽器

對於瀏覽器來講,全部的接口均是基於XHR和Fetch實現的,爲了捕獲接口中的錯誤,能夠經過重寫該方法,而後經過接口返回的信息來判斷當前接口的情況,下面以XHR爲例來展現封裝過程。
function newXHR() {
    const XMLHttpRequest = window.XMLHttpRequest;
    const oldXHROpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = (method, url, async) => {
        // 作一些本身的數據上報操做
        return oldXHROpen.apply(this, arguments);
    }

    const oldXHRSend = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = (body) => {
        // 作一些本身的數據上報操做
        return oldXHRSend.apply(this, arguments);
    }
}

3.1.4 業務信息

每一個產品都會有本身的業務信息,例如用戶在線時長、pv、uv、用戶分佈等,經過獲取這些業務信息才能更加清楚的瞭解目前產品的情況,以便產品經理更好的去規劃產品的將來方向。因爲每一個產品業務信息多種多樣,小夥伴本能夠按照本身的需求進行撰寫代碼,此處我就再也不贅述。

3.2上報

對於上報的方式無外乎兩種:一種是Ajax的方式上報;另外一種是經過Image的形式進行上報。目前不少大廠採用的上報方式均是經過一個1*1像素的的gif圖片進行上報,既然人家都採用該種策略,那咱們就來嘮一嘮下面兩個問題。
  • 爲何採用Image的方式上報?<br/>安全

    1. 沒有跨域問題。由於數據服務器和後端服務器大機率是不一樣的域名,若採用Ajax的方式進行處理還要處理跨域問題,不然數據會被瀏覽器攔截。<br/>
    2. 不會阻塞頁面加載,只需new Image對象便可。
  • 圖片類型不少,爲何採用gif這種格式進行上報?<br/>
    其實歸結爲一個字——小。對於1*1px的圖片,BMP結構的文件須要74字節,PNG結構的文件須要67字節,GIF結構的文件只須要43字節。一樣的響應,GIF能夠比BMP節約41%的流量,比PNG節約35%的流量,因此選擇gif進行上報。

3.3分析

日誌上報以後須要進行清洗,獲取本身所須要內容,並將分析內容進行存儲。根據數據量的大小可分爲兩種方式:單機和集羣。

1、單機<br/>

訪問量小、日誌少的網站能夠採用單機的方式對數據進行分析,例如用node讀取日誌文件,而後經過日誌文件中獲取所須要的信息,最終將處理的信息存儲到數據庫中。<br/>

2、集羣<br/>

不少產品的訪問量很大,日誌不少,此時就須要利用Hadoop進行分佈式處理,獲取最終處理結果,其處理流程圖以下所示:

根據本身的日誌量級決定本身的分析方式,合適的就是最好的,不用一味追求最優的、最早進的處理方式。

3.4報警

當異常類型超多必定閾值以後須要進行報警通知,讓對應的工做人員去處理問題,及時止損。根據報警的級別不一樣,能夠選擇不一樣的報警方式。
  1. 郵件——普通報警
  2. 短信——嚴重報警,已影響部分業務
  3. 電話——特別嚴重,例如系統已宕機

1.若是以爲這篇文章還不錯,來個分享、點贊、吧,讓更多的人也看到

2.關注公衆號執鳶者,領取學習資料,按期爲你推送原創深度好文

參考

http://www.alloyteam.com/2020...
https://www.colabug.com/2019/...
image

相關文章
相關標籤/搜索