Can I use the browser Navigation Timing API for Ajax events in single page apps? If not, what's a good tool?

最后都变了- 提交于 2019-11-28 06:00:39

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.

Ionut Popa

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

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.

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

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!