天天看点

第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​

​的监控方法做一个简单的实现,后面会接着分析相关的问题。

未完待续...

继续阅读