找出Ajax请求完成所需的时间是多久

63

如何找出特定的 $.ajax() 请求花费了多长时间?我想获取这些信息并在页面上显示。

回答??::::

我对 JavaScript 还很陌生,以下是我能想到的最佳方法(如果您不想将 "success" 函数嵌入其中,因为它将是一个更大的函数)。这是一个好方法吗?我觉得我可能把事情复杂化了...

makeRequest = function(){
    // Set start time
    var start_time = new Date().getTime();

    $.ajax({ 
        async : true,
        success : getRquestSuccessFunction(start_time),
    });
}

getRquestSuccessFunction = function(start_time){
    return function(data, textStatus, request){
        var request_time = new Date().getTime() - start_time;
    }
}

可能是 http://stackoverflow.com/questions/1188195/ajax-jquery-response-time-performance-widget 的重复问题,顺便说一下,那个问题还没有得到解答。 - Wolph
@Wolph 这个链接的问题已经被标记为与这个问题重复。我不明白这怎么可能。 - www139
1
@www139:这个问题更好,所以那个被标记为重复了。而且,这个问题有更好的答案。 - Wolph
1
Google Chrome使这变得非常容易,转到您想要测量Ajax请求的URL,打开开发人员控制台并转到网络选项卡 - 每次请求通过时,它都会显示在此处。 - A Friend
10个回答

59

@codemeit 是正确的。他的解决方案使用 jQuery 进行 ajax 请求,类似以下代码。此代码将以毫秒返回请求时间。

@codemeit 是正确的。他的解决方案使用 jQuery 进行 ajax 请求,类似以下代码。此代码将以毫秒返回请求时间。

var start_time = new Date().getTime();

jQuery.get('your-url', data, function(data, status, xhr) {
        var request_time = new Date().getTime() - start_time;
});

3
我对JavaScript还不熟悉。这里使用了一个唯一的start_time变量,还是会在异步请求中被覆盖? - Chris Dutrow
7
这种方式无法适用于多个请求,即使进行了反对投票。 - Anonymous
你需要创建一个请求数组,在ajax的beforeSend()函数中推入start_time - 然后在success()函数中计算时间差。 - Ross
4
如果你想要更精确的时间粒度,可以使用window.performance.now() - benjaminz

26

这是正确的做法。

$.ajax({
    url: 'http://google.com',
    method: 'GET',
    start_time: new Date().getTime(),
    complete: function(data) {
        alert('This request took '+(new Date().getTime() - this.start_time)+' ms');
    }
});

https://jsfiddle.net/0fh1cfnv/1/


1
这里的 start_time 是否与 ajax 有关或者特殊?还是说你可以像这样在 ajax 对象中声明任何你喜欢的键呢?如果是这样的话,那真的很酷,我之前没有想到过! - GrayedFox
1
这里还有一些事件队列方面的保证吗?我的意思是,我们知道以这种方式声明start_time将实际上初始化该变量作为请求开始之前的指令,还是有可能在请求开始之前有其他事情会悄悄地插入队列(弄脏结果)? - GrayedFox
2
这个jQuery函数立即启动请求,由于开始时间是即时声明的,所以您不会搞砸它。参数也是一个对象,因此添加自定义属性也没有问题。 - Anonymous
简单而精妙!+1 将自己的变量添加到对象中以保持开始时间的技巧是基本的JavaScript,即使在没有jQuery的情况下创建ajax调用也可以使用。 - Roland

10

这不会给出准确的时间,因为 Javascript 使用事件队列。这意味着您的程序可能会像这样执行:

  • 开始 AJAX 请求
  • 处理等待的鼠标点击事件/任何其他等待的代码行
  • 开始处理 AJAX 准备好的响应

很遗憾,据我所知,没有办法获取事件被添加到队列的时间。Event.timeStamp 返回事件从队列中弹出的时间,请参见此 fiddle:http://jsfiddle.net/mSg55/

Html:

<a href="#">link</a>
<div></div>

JavaScript:

$(function() {
    var startTime = new Date();
    $('a').click(function(e) {
        var endTime = new Date(e.timeStamp);
        $('div').append((endTime - startTime) + " ");
        //produce some heavy load to block other waiting events
        var q = Math.PI;
        for(var j=0; j<1000000; j++)
        {
            q *= Math.acos(j);
        }
    });

    //fire some events 'simultaneously'
    for(var i=0; i<10; i++) {
        $('a').click();
    }
});

6
阿里斯托特利斯关于事件队列的说法是正确的。你可以将时间戳创建放入一个尽可能靠近 AJAX 请求开始执行的代码段中。
当前稳定版本的 jQuery(撰写时为 2.2.2)有一个名为 beforeSend 的键,它接受一个函数。我会在那里完成这个操作。
请注意,在 JavaScript 中,所有声明在函数之外的全局范围变量都会在程序启动时初始化。了解 JavaScript 范围将有助于此处的操作。
棘手的部分是访问在 beforeSend 函数中声明的变量,在 success 回调中无法轻松访问。如果您在本地声明它(使用 let),则无法轻松地在该函数范围之外访问它。
以下示例将提供稍微更准确的结果(注意:在大多数情况下!),但也很危险,因为它声明了一个全局范围变量(start_time),可能会与同一页上的其他脚本产生不良互动等问题。

我很想深入了解JavaScript原型bind函数的世界,但这超出了范围。这里有一个替代答案,请小心使用,并在生产之外使用。

'use strict';
$.ajax({
    url: url,
    method: 'GET',
    beforeSend: function (request, settings) {
        start_time = new Date().getTime();
    },
    success: function (response) {
        let request_time = new Date().getTime() - start_time;
        console.log(request_time);
    },
    error: function (jqXHR) {
        console.log('ERROR! \n %s', JSON.stringify(jqXHR));
    }
]);

如果在节点前缀中使用全局声明,请在其前面加上 GLOBAL.。再次强调,不要在任何生产环境中使用此功能! - GrayedFox

3
你可以将开始时间设置为一个变量,当AJAX动作完成时计算时间差。你可以使用Firefox插件Firebug来检查AJAX请求和响应的性能。或者你可以使用Charles代理或Fiddler来嗅探流量以查看性能等信息。 http://getfirebug.com/

1

这样怎么样:

首先全局设置请求对象的属性TimeStarted

$(document).ajaxSend(function (event, jqxhr, settings) {
    jqxhr.TimeStarted = new Date();
});

然后调用任何ajax。
var request = $.ajax({ 
    async : true,
    success : function(){
    alert(request.TimeStarted);
   },
});

0
这是我的观点:

const clock = () => {
const start = new Date().getTime();

return {
    measure: () => {
        const completed = new Date().getTime();

        return completed - start;
    },
};
};

const httpClient = async () => new Promise((res) => setTimeout(res, 1000));

const makeRequest = async () => {
const { measure } = clock();

await httpClient();

const result = measure();

console.log(`Request took ${result}ms`);
};

makeRequest();


0

我稍微调整了一下,得到了一个通用函数,可以用于所有的ajax调用。这意味着你不必为每个单独的ajax调用做同样的事情。

var start_time;   
$.ajaxSetup({
  beforeSend: function () {
    start_time = new Date().getTime();
  },
  complete: function () {
    var request_time = new Date().getTime() - start_time;
    console.log("ajax call duration: " + request_time);
  }
});

这对于重叠的Ajax调用也不起作用。start_time将被覆盖。 - ChristoKiwi

0

你可以使用以下代码片段...

var d1 = new Date();  
$.ajax({
    type: 'GET',
    contentType: "application/json; charset=utf-8",
    url: '/Survey/GET_GetTransactionTypeList',
    data: {},
    dataType: 'json',
    async: false,
    success: function (result) {
        var d2 = new Date();
        var seconds = (d2 - d1) / 1000;
        console.log(seconds);           
    },
    error: function (request, status, error) {
        alert(request.statusText + "/" + request.statusText + "/" + error);
    }
}); 

如果你想减少ajax调用的初始化时间,只需将async值设置为false而不是true。像这样的方式...
async: false,

0
makeRequest = function(){

    // Set start time
    console.time('makeRequest');

    $.ajax({ 
        async : true,
        success : getRquestSuccessFunction(start_time),
    });
}

getRquestSuccessFunction = function(start_time){

    console.timeEnd('makeRequest');

    return function(data, textStatus, request) {

    }
}

这将以毫秒为单位输出结果,例如makeRequest:1355.4951171875ms


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接