2

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?

explunit
  • 18,967
  • 6
  • 69
  • 94
Cherian
  • 19,107
  • 12
  • 55
  • 69
  • What version of Chrome are you using? I ask because I tested 14.0.794.0 (Mac) using this demo http://webtimingdemo.appspot.com/ and I see loadEventStart as a value. – Kinlan Jun 19 '11 at 10:00
  • @Kinlan i get the values as shown in demo when i hit the page, its the code i posted above is the problem – Cherian Jun 19 '11 at 12:36

3 Answers3

5

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.

NicJ
  • 4,070
  • 1
  • 25
  • 18
3

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);
});
Kinlan
  • 16,315
  • 5
  • 56
  • 88
0

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) {
BenH
  • 167
  • 3
  • 10