Can I use the browser Navigation Timing API for Aj

2019-01-17 05:13发布

问题:

We've got a single page app built with Knockout and Backbone which makes Ajax calls to the server and does some complex data caching and DOM rendering. We're really like to measure the performance (and log it back to the server) as seen by the user. I can't seem to get my head wrapped around whether the browser Navigation Timing API is going to be useful for this or not. From what I see in examples, the Navigation Timing API is tied to window.performance and this is limited to the page load and not suitable for monitoring Ajax behavior. True or false? If false, what else can I use?

I'd love to set custom instrumentation points between which to measure time, e.g. for an Ajax call that does some DOM rendering with a server result.

回答1:

1 - True, window.performance is tied to page load. See example below which shows this:

    <button id='searchButton'>Look up Cities</button>
    <br>
    Timing info is same? <span id='results'></span>
    <script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
    <script type="text/javascript">
        jQuery('#searchButton').on('click', function(e){
            // deep copy the timing info
            var perf1 = jQuery.extend(true, {}, performance.timing);             
            // do something async
            jQuery.getJSON('http://ws.geonames.org/searchJSON?featureClass=P&style=full&maxRows=10&name_startsWith=Denv', function() {
                // get another copy of timing info
                var perf2 = jQuery.extend(true, {}, performance.timing);
                // show if timing information has changed
                jQuery('#results').text( _.isEqual( perf1, perf2 ) );
            });
            return false;
        });
    </script>

Also, even if you did get it working you'd have missing data from old browsers that don't support this object.

2 - The Boomerang project seems to go beyond the web timing API and also supports older browsers. There is a talk with slides and sample code by the current maintainer listed in this conference. Sorry no direct link.



回答2:

You can now use the User Timing API (W3C Recommendation 12 December 2013) which provides a way that you can insert API calls at different parts of your Javascript and then extract detailed timing data.

You do that using mark(), it lets you work out how much time it took you hit that ‘mark’ in your web application, and then measure() to calculate the time elapsed between your marks.

For your specific case you can have something like this:

app.render = function(content){
  myEl.innerHTML = content;
  window.performance.mark('end_render');
  window.performance.measure('measure_render', 'start_xhr', 'end_render');
};


var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onload = function(e) {
  window.performance.mark('end_xhr');
  window.performance.measure('measure_xhr', 'start_xhr', 'end_xhr');
  app.render(e.responseText);
}
window.performance.mark('start_xhr');
myReq.send();


回答3:

There seems to be patchy support for window.performance.getEntries(), which will give you details of all resources loaded into a page along with their URLs. I use this API for jsonp (not XMLHttpRequest) requests in AzurePing.info for the browsers that support it, falling back to new Date().getTime() for those that don't.

At time of writing, IE 10 and Chrome support getEntries, but Firefox does not. Unfortunately, not all the timing properties are set - even in Chrome and IE. All I could rely on was a fetchStart, responseEnd, and duration.

Sample source is on GitHub.



回答4:

The Navigation Timing API is in my opinion not really helpful when it comes to measuring single page application performance.

Along with the already mentioned User Timing API, the Resource Timing API is actually much more helpful. This API provides functionality to retrieve the timings for all requests made in a user session (actually all you see in the network tabs of the developer tools in most browsers). These timings include Round-Trip times as well as DNS-lookup times etc.

Unfortunately, this is a relatively new specification and is not yet implemented accross all browsers. Chrome and IE > 10 provide implementations (although not yet complete). Surprisingly, IE seems to have implemented the most unitl now...



回答5:

There are two ways to do it

  1. Resource Timing API
  2. Wrapping XMLHTTPRequest

Lets see the differences between them.

1. Resource Timing API

Browsers add supports for Resource Timing API recently. Resource Timing API basically has timing information about each and every resources loaded from app. It may be css, javascript or AJAX requests. You can get list of resources details as

  performance.getEntriesByType('resource');

It will return array of object where you can find AJAX requests by initiatorType which is equal to xmlhttprequest. But there are some limitation.

  1. By default, maximum resource size is 150. Above array only have maximum of 150 resources. If you want more, you can increase buffer size as performance.setResourceTimingBufferSize(500).
  2. You will not get information about whether the AJAX requests is succeed or failed.

2. Wrapping XMLHTTPRequest

If you can wrap your XMLHTTPRequest API, you will get all information that you need from timing, status code and byte size. But you have to write lot of code and ofcourse test, test and test.

[Disclaimer] I work for atatus.com where we help you to measure page load time, AJAX timing and custom transaction. Also you can see session traces about how each and every resources perform.