Find out how long an Ajax request took to complete
Asked Answered
G

10

64

What is a good way to find out how long a particular $.ajax() request took?

I would like to get this information and then display it on the page somewhere.

ANSWER??::::

I'm new to javascript, this is the best that I could come up with if you don't want to inline the "success" function (because it will be a much bigger function) Is this even a good way to do this? I feel like I'm over complicating things...:

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;
    }
}
Gelatinous answered 17/8, 2010 at 0:41 Comment(4)
Possible duplicate of #1188695 Which hasn't been answered by the way.Predisposition
@Predisposition The linked question has been flagged duplicate of this very question. I don't understand how this could even be possible.Dupe
@www139: this question was better so that one has been marked as a duplicate for this one. Also, this one has better answersPredisposition
Google chrome makes this very easy, go to the url that you want to measure ajax requests on, open dev console and go to the network tab - every time a request goes through it will show up hereKileykilgore
D
60

@codemeit is right. His solution looks something like the following using jQuery for the ajax request. This returns the request time in milliseconds.

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

jQuery.get('your-url', data, function(data, status, xhr) {
        var request_time = new Date().getTime() - start_time;
});
Droughty answered 17/8, 2010 at 0:51 Comment(4)
I'm new to javascript. Will this use a unique start_time variable, or will it get overwritten for asynchronous requests?Gelatinous
This will not work for multiple requests, downvotingOrdination
You need to create an array of requests, push start_time in the beforeSend() function in ajax - then in the success() function calculate the time difference.Empire
Use window.performce.now() if you want more granularityRetrospect
O
27

This is the proper way to do it.

$.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/

Ordination answered 12/3, 2017 at 2:25 Comment(4)
Is start_time here somehow special/related to ajax or can you simply declare any key you like inside the ajax object like this? If so that's really cool, I didn't think about that...!Christen
Also are there some guarantees here event queue wise? I mean - do we know that declaring start_time in this manner will in fact initialise that variable as the instruction that precedes the start of the request, or is there a chance some other things could sneak into the queue before the request starts (dirtying up results)?Christen
This jquery function immediately initiates the request, and since the start time is declared on the fly - no, you won't be able to mess it up. The argument is also an object, so it doesn't hurt adding custom properties to it.Ordination
Brillant in its simplicity! +1 The trick of adding your own variable for keeping the start time to the object is basic javascript, and will work also when creating the ajax call without jquery.Waistband
P
10

This will not give accurate timings because javascript uses an event queue. That means your program may execute like this:

  • Start AJAX request
  • Handle a waiting mouse click event / any other waiting line of code in the meantime
  • Start handling the AJAX ready response

Unfortunately there is no way to get the time the event was added to the queue as far as I know. Event.timeStamp returns the time the event was popped from the queue, see this 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();
    }
});
Puente answered 3/7, 2014 at 10:37 Comment(0)
C
6

Aristoteles is right about the event queue. What you can do is slip your timestamp creation into a section of code you know will be executed as close as possible to the beginning of the AJAX request.

The current stable version of jQuery (at time of writing: 2.2.2) has a beforeSend key which accepts a function. I would do it there.

Note that in JavaScript, all globally scoped variables that are declared outside of a function are initialized as soon as the program starts up. Understanding JavaScript scope will help here.

The tricky part is accessing the variable you declared in the beforeSend function in the success callback. If you declare it locally (using let) you can't easily access it outside of that function's scope.

Here is an example which will give slightly more accurate results (caveat: in most cases!) which is also dangerous since it declares a globally scoped variable (start_time) which could interact badly with other scripts on the same page, etc.

I would love to dive into the world of JavaScript's prototype bind function but it's a bit out of scope. Here is an alternate answer, use with care, and outside of production.

'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));
    }
]);
Christen answered 15/4, 2016 at 13:3 Comment(1)
If in the node prefix the global declaration with GLOBAL.. Again... do NOT use this in production, anywhere!Christen
C
3

You can set the start time to a var and calculate the time difference when the AJAX action completed.

You can utilise Firefox plug-in Firebug to check the performance of the AJAX request and response. http://getfirebug.com/ Or you could utilise Charles proxy or Fiddler to sniff the traffic to see the performance etc.

Cannelloni answered 17/8, 2010 at 0:43 Comment(0)
H
1

How About This:

First Globally Set the property TimeStarted with the request object.

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

And then call any ajax

var request = $.ajax({ 
    async : true,
    success : function(){
    alert(request.TimeStarted);
   },
});
Haggadah answered 5/10, 2018 at 11:50 Comment(0)
H
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) {

    }
}

this gives output in mseconds like makeRequest:1355.4951171875ms

Hegarty answered 4/8, 2017 at 15:32 Comment(0)
S
0

I fiddled a bit and got a generic function that can be displayed for all ajax calls. This means that you don't have to do the same thing for every single ajax call

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);
  }
});
Sieve answered 20/12, 2018 at 14:42 Comment(1)
This also wont work for overlapping Ajax calls. start_time will get overwritten.Bijugate
N
0

You may use the below code spinet.....

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);
    }
}); 

If you want to reduce ajax call init duration, just set async value as false instead of true. Like this ways....

async: false,
Nakitanalani answered 27/6, 2020 at 5:33 Comment(0)
S
0

Here's my take:

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();
Surveyor answered 11/11, 2023 at 8:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.