Cherian
Cherian

Reputation: 19418

Erroneous values in WebTiming API

I am using the new webTiming API exposed through Chrome and IE 9 specified in the new W3C spec.

For some reason I am getting the loadEventEnd as 0. This is restricting me from calculating the real load time.

Here’s the output and code

connectStart is: 1308411426685
responseStart is: 1308411429541
domLoading is: 1308411429548
connectEnd is: 1308411426685
domInteractive is: 1308411430023
fetchStart is: 1308411426667
secureConnectionStart is: 0
domainLookupStart is: 1308411426667
responseEnd is: 1308411429543
requestStart is: 1308411426685
loadEventEnd is: 0
domComplete is: 0
redirectStart is: 0
unloadEventEnd is: 1308411429545
domContentLoadedEventStart is: 1308411430023
domContentLoadedEventEnd is: 0
domainLookupEnd is: 1308411426667
navigationStart is: 1308411426667
unloadEventStart is: 1308411429545
loadEventStart is: 0
redirectEnd is: 0

Code:

var performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {};
var timing = performance.timing || {};
function getTiming(timingStr) {
    if (!timing) return 0;
    var time = timing[timingStr];
    return time;
}
var loadTime = (new Date().getTime() - getTiming("navigationStart"))/1000;
$(document).ready(function(){
    var perflist = '<ul id=perflist>';
    for(var performer in timing){
        var j = getTiming(performer);
        perflist += '<li>' + performer  + ' is: ' + j + '</li>';
    }
    perflist += '</ul>';
    $("body").prepend(perflist);
    $("#adminmenu").prepend("<li>Load time : " + loadTime + " seconds</li>");

Can someone help me figure out what’s wrong?

Upvotes: 2

Views: 1948

Answers (3)

NicJ
NicJ

Reputation: 4155

The reason you are seeing loadEventEnd: 0 (as well as loadEventStart: 0 for that matter) is because you are checking the value in $(document).ready().

$(document).ready() is fired by jQuery when the DOM is fully loaded. This will be prior to the window's onLoad event firing, which will only occur once all external content (eg CSS and images) have been downloaded.

For a better visualization of the browser's NavigationTiming timeline, refer to the image below: NavigationTiming

$(document).ready() is fired essentially after domContentLoaded, prior to domComplete, and clearly before loadEventStart and loadEventEnd (e.g. the window's onLoad event has fired).

Note you should not just change your code to run during the window onLoad event, as loadEventEnd will still be 0 during the onLoad event. The definition of loadEventEnd in the NavigationTiming spec is:

This attribute must return the time when the load event of the current document is completed. It must return zero when the load event is not fired or is not completed.

The solution is to ignore loadEventEnd (and use loadEventStart or event window.performance.now()) during the onLoad event, or, to setTimeout(..., 0) during the onLoad event and query the performance data during that callback, as it will then be after onLoad so all timestamps should be filled in. It's really dependent on what timestamps matter to you.

Upvotes: 5

BenH
BenH

Reputation: 167

If you're using jQuery, the easiest way is to call your function when the loadEventEnd fires.

So, replace

$(document).ready(function(){

with:

$(window).load(function(){

Too, you'll get JS errors in browsers that don't have the timing interface. You'll want something like this to validate that the interface exists before trying to execute. What you have above is ok when the browser does have the interface. Otherwise, try this for your check:

 $(window).load(function(){
     if (window.performance != undefined) {
        var e = window.performance;
        if (e.timing) {

Upvotes: 0

Kinlan
Kinlan

Reputation: 16607

If you look at the source code in http://webtimingdemo.appspot.com/ it runs the code AFTER onload (setTimeout('writeTimings()', 0)), your code runs in $(document).ready() which runs before onload as it runs on DOMContentLoaded in Chrome.

I have put a setTimeout into your code and now it works: See http://jsbin.com/acabo4/8

var performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {};
var timing = performance.timing || {};
function getTiming(timingStr) {

    if (!timing) return 0;
    var time = timing[timingStr];
    return time;
}
var loadTime = (new Date().getTime() - getTiming("navigationStart"))/1000;
$(document).ready(function() {

  setTimeout(function(){
    var perflist = '<ul id=perflist>';
    for(var performer in timing){
        var j = getTiming(performer);
        perflist += '<li>' + performer  + ' is: ' + j + '</li>';
    }
    perflist += '</ul>';
    $("body").prepend(perflist);
    $("#adminmenu").prepend("<li>Load time : " + loadTime + " seconds</li>")
  }, 100);
});

Upvotes: 3

Related Questions