天天看點

第113期:前端性能監控方案思考(監控request 請求)

這裡記錄工作中遇到的技術點,以及自己對生活的一些思考,周三或周五釋出。

封面圖

第113期:前端性能監控方案思考(監控request 請求)

前端監控主要監控的内容有幾個方面:js錯誤,request請求,用使用者行為以及相關性能名額。

對于request請求的監控,主要監控的時間點在于​

​發起請求時​

​​以及​

​收到請求時​

​兩個時間節點。在發起請求時,我們可以擷取到請求的方法,位址資訊。在收到請求時,我們可以計算請求花費的時長等我們想要的資訊。

用什麼技術點

XMLHttpRequest

想要實作對請求的監控,需要我們的對頁面中的請求進行攔截。

界面中的請求通常使用​

​XMLHttpRequest​

​​對象發送請求,即便我們使用了諸如​

​axios​

​​的庫,其内部的實作方式也是對​

​XMLHttpRequest​

​​進行封裝,以簡化我們的請求操作,是以在正式開始之前我們需要對​

​XMLHttpRequest​

​常用的屬性和方法有一個簡單的了解。

  • ​XMLHttpRequest.open(method, url, async, user, password )​

    ​​。

    這個方法用來初始化一個請求。通過這個方法,我們可以擷取到請求的method, url, async, user, password資訊。

  • ​XMLHttpRequest.send()​

    ​​ 。

    這個方法用來發送一個請求。如果是異步請求(預設為異步請求),則此方法會在請求發送後立即傳回;如果是同步請求,則此方法直到響應到達後才會傳回。

想要監聽到相應的内容,需要我們對能夠接收到響應的資料。需要我們了解下面兩個事件。

  • ​load​

    ​​事件。

    當一個​​XMLHttpRequest​​請求完成的時候會觸發​

    ​load​

    ​ 事件。我們可以給​

    ​XMLHttpRequest​

    ​對象添加load事件以監控請求結果。比如:
const addListener = (xhr) => {
    xhr.addEventListener('load', (msg)=>{console.log(msg)});
  }

  const http= (method,url)=>{
      let xhr = new XMLhttpRequest();
      addListener(xhr)
      xhr.open(method,url)
      xhr.send()
  }      
  • ​error​

    ​​事件。

    當請求遇到錯誤時,将觸發​

    ​error​

    ​ 事件。和​

    ​load​

    ​事件一樣,我們可以監聽​

    ​XMLHttpRequest​

    ​對象的load事件以監控請求錯誤資訊。示例:
const addListener = (xhr) => {
   xhr.addEventListener('error', (msg)=>{console.log(msg)});
 }

 const http= (method,url)=>{
     let xhr = new XMLhttpRequest();
     addListener(xhr)
     xhr.open(method,url)
     xhr.send()
 }      

了解了這幾個方法,足夠我們對request請求一個簡單的監控。

實作方式

在具體實施上,其原理就是對這些方法進行劫持,或者重寫。

實作的方式之一就是重寫​

​XMLHttpRequest​

​對象上的方法,使之具有擷取以及上報資料的能力。比如,這裡使用console将發送請求的相關資訊列印出來。

let orignOpen = XMLHttpRequest.prototype.open

    function Fopen  (method,url,async,username,password){
        console.log('request info need report-----',method,url,async,username,password)
        orignOpen.call(this,method,url,async,username,password)
    }

    XMLHttpRequest.prototype.open = Fopen      

此時,我們執行代碼。然後發起請求,就可以看到我們想要的資訊。

第113期:前端性能監控方案思考(監控request 請求)

我這裡是用node模拟了一個登入接口。

相比于使用自己定義方法來重寫​

​open​

​​方法,我們也可以使用​

​proxy​

​來對它做一層代理,不管我們用什麼方法,本質上都是對open方法進行一層包裝,使它可以列印,收集到我們想要的資訊。

比如:

export const resetOpen2 = () => {
    const handler =  {
        apply:function(target,thisArg,argumentsList){
            console.log('thisArg',thisArg)
            console.log('argumentsList',argumentsList)
            return target.call(thisArg,argumentsList[0],argumentsList[1])
        }
    }
    XMLHttpRequest.prototype.open = new Proxy(XMLHttpRequest.prototype.open,handler)
}      

調用​

​resetOpen2​

​方法,我們就可以監聽到請求的方法以及請求的URL位址等資訊。

第113期:前端性能監控方案思考(監控request 請求)

同理,我們可以使用​

​proxy​

​對send方法進行重寫,使它可以監聽send方法。

export const resetSend = () => {
    const handleSendResule = (res)=> {
        console.log('send-res',res)
    }
    const handler =  {
        apply:function(target,thisArg,body){
            thisArg.addEventListener('load',handleSendResule)
            thisArg.addEventListener('error',handleSendResule)
            return  target.call(thisArg,body)
        }
    }
    XMLHttpRequest.prototype.send = new Proxy(XMLHttpRequest.prototype.send,handler)
}      

結果如下:

第113期:前端性能監控方案思考(監控request 請求)

這樣,我們就可以簡單的對​

​XMLHttpRequest​

​進行一定程度的監控。但是,僅僅能夠監控還是不夠的,我們需要對請求時間進行計算。

怎麼計算呢? 需要我們有一個比較好的方法。

先寫到這裡吧,明天繼續...

最後

這篇僅僅對​

​XMLHttpRequest​

​的監控方法做一個簡單的實作,後面會接着分析相關的問題。

未完待續...

繼續閱讀