warm-stranger

前端监控系统 目前已经上线,欢迎使用!

随着前端项目的权重不断加大,前后端分离也变得越来越有必要。前端项目开始承担着更多的功能和责任,所以前端性能的优化就变得很重要了。

对于一个前后端分离的前端项目,接口获取数据是必不可少的,所以接口的优化直接关系到用户体验的问题,那么,我们怎么知道线上项目的接口状态是否良好呢?

一、如何去判断页面上接口请求的质量

对于一个html页面, 发出最少的请求,每个接口请求消耗最短的时间为最佳

  1. 因为用户远在千里之外,页面上每发一个请求的代价都是巨大的,代价越高,风险就会越高,当一个接口请求发生了一系列的不利的结果将直接导致用户体验差,这是我们前端工程师所不能够接受的。而且对于高并发的前端项目来说,过多的接口请求,对服务器造成的压力也是不容小觑的,所以我们要尽量减少一个页面上的请求数量。
  2. 接口耗时是影响用户体验的一个重要因素,用户从某个动作开始发出请求,到得到相应的反馈结果,这个时间段不可以太长,否则用户会以为程序死掉,或者直接放弃。

以上图为例,所有的接口请求耗时都是毫秒级别,而且浮动不大,比较稳定,我们可以视为优良。 但是第二个表中展示,平均每个页面发出的请求次数居然有达到14次之多,这就是需要优化的地方了

二、分析页面上的ajax请求方式

如我们所知,比较常用的ajax请求方式有,jquery分装的ajax方法,目前正在流行的fetch方法,或者直接调用XMLHttpRequest来发送请求。 虽然方式有三种,但是我们可以看看jquery.ajax() 和 fetch的源码

Jquery.ajax 源码:

// Functions to create xhrs
function createStandardXHR() {
	try {
		return new window.XMLHttpRequest();
	} catch( e ) {}
}
function createActiveXHR() {
	try {
		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
	} catch( e ) {}
}
// Create the request object
// (This is still attached to ajaxSettings for backward compatibility)
jQuery.ajaxSettings.xhr = window.ActiveXObject ?
	/* Microsoft failed to properly
	 * implement the XMLHttpRequest in IE7 (can't request local files),
	 * so we use the ActiveXObject when it is available
	 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
	 * we need a fallback.
	 */
	function() {
		return !this.isLocal && createStandardXHR() || createActiveXHR();
	} :
	// For all other browsers, use the standard XMLHttpRequest object
	createStandardXHR;

fetch 源码:

self.fetch = function(input, init) {
    fetchHttpUrl = input;
    return new Promise(function(resolve, reject) {
      var request = new Request(input, init)
      var xhr = new XMLHttpRequest()

      xhr.onload = function() {
        // ....
      }
      // ...
      xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
    })
  }

其实不难看出, jquery的ajax, fetch方法都是通过 new XMLHttpRequest() 创建了一个XMLHttpRequest的对象,然后做了一系列的异步请求操作。

既然清楚这一点了,那么我们监控页面上的请求,就会简单很多了。

三、如何去监控页面上发出的请求呢?

根据第一点,我们需要分析的是,接口的平均请求耗时,和每个页面的请求频次。那么就需要记录下接口的请求次数,和每个接口的请求时间

先看一段代码:

function ajaxEventTrigger(event) {
      var ajaxEvent = new CustomEvent(event, {
        detail: this
      });
      window.dispatchEvent(ajaxEvent);
    }
var oldXHR = window.XMLHttpRequest; 
function newXHR() {
      var realXHR = new oldXHR();
      realXHR.addEventListener('abort', function () { ajaxEventTrigger.call(this, 'ajaxAbort'); }, false);
      realXHR.addEventListener('error', function () { ajaxEventTrigger.call(this, 'ajaxError'); }, false);
      realXHR.addEventListener('load', function () { ajaxEventTrigger.call(this, 'ajaxLoad'); }, false);
      realXHR.addEventListener('loadstart', function () { ajaxEventTrigger.call(this, 'ajaxLoadStart'); }, false);
      realXHR.addEventListener('progress', function () { ajaxEventTrigger.call(this, 'ajaxProgress'); }, false);
      realXHR.addEventListener('timeout', function () { ajaxEventTrigger.call(this, 'ajaxTimeout'); }, false);
      realXHR.addEventListener('loadend', function () { ajaxEventTrigger.call(this, 'ajaxLoadEnd'); }, false);
      realXHR.addEventListener('readystatechange', function() { ajaxEventTrigger.call(this, 'ajaxReadyStateChange'); }, false);
      return realXHR;
}
window.addEventListener('ajaxLoadEnd', function(e) {
      // 记录日志的逻辑
});
window.addEventListener('ajaxError', function(e) {
});

数据库字段设计如下:

OK, 接口请求统计完成了。

相关文章: