New issue
Advanced search Search tips

Issue 828356 link

Starred by 2 users

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Bug



Sign in to add a comment

loadEventEnd is not zero while document.readyState is interactive

Reported by nn1436...@gmail.com, Apr 3 2018

Issue description

UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0

Steps to reproduce the problem:
Not sure how to do it exactly.
I have an extension that receives asynchronous response from background script.

Navigate to http://help.dottoro.com/ljxsrgqe.php
Break in the middle.

What is the expected behavior?
performance.timing.loadEventEnd is zero whenb document.readyState is "loading"

What went wrong?
performance.timing.loadEventEnd has value while document.readyState is "loading" and not "complete"

performance.timing
 PerformanceTiming {
 connectEnd: 0
 connectStart: 0
 domComplete: 1522751705086
 domContentLoadedEventEnd: 1522751705086
domContentLoadedEventStart: 1522751705086
domInteractive: 1522751705086
domLoading: 1522751705017
domainLookupEnd: 0
domainLookupStart: 0
fetchStart: 0
loadEventEnd: 1522751705086
loadEventStart: 1522751705086
navigationStart: 1522751705017
redirectEnd: 0
redirectStart: 0
requestStart: 0
responseEnd: 1522751705017responseStart: 0
secureConnectionStart: 0unloadEventEnd: 0
unloadEventStart: 0
__proto__: PerformanceTiming

document.readyState
"loading"

According to spec https://www.w3.org/TR/navigation-timing :

loadEventStart attribute

This attribute must return the time immediately before the load event of the current document is fired. It must return zero when the load event is not fired yet.
loadEventEnd attribute

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.

Did this work before? N/A 

Chrome version: 65  Channel: n/a
OS Version: 10.0
Flash Version: Shockwave Flash 29.0 r0
 
Labels: Needs-Triage-M65
Components: Blink>PerformanceAPIs
Components: -Blink>PerformanceAPIs Blink>PerformanceAPIs>NavigationTiming

Comment 4 by npm@chromium.org, Apr 5 2018

Cc: npm@chromium.org
We set the LoadEventEnd right after dispatching the load event https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp?type=cs&sq=package:chromium&l=1479

But I think you're right that document.readyState should be complete at this point. 'Break in the middle.' doesn't really say how to reproduce this... Is document.readyState equal to complete on document.onload?
It was not easy but I succeeded with simple html file.

Check this:
https://jsbin.com/dajiwus/1

Code:


function t() {
    if (performance.timing.loadEventEnd!==0) {
        alert("document.readyState: " + document.readyState + ", performance.timing.loadEventEnd: " + performance.timing.loadEventEnd);
    }
}

document.onreadystatechange = function() {
    setTimeout(t,0);
}
window.onload = function(){
document.write('<img src="https://techcrunch.com/wp-content/uploads/2017/05/onedrive-illo3.jpg?w=1390&crop=1">');
}

Comment 6 by npm@chromium.org, Apr 6 2018

I don't think this is a NavigationTiming bug. I slightly changed the html to this to see what the state is during onload

function t() {
    if (performance.timing.loadEventEnd!==0) {
        console.log("document.readyState: " + document.readyState + ", performance.timing.loadEventEnd: " + performance.timing.loadEventEnd);
    }
}

document.onreadystatechange = function() {
    setTimeout(t,0);
}
window.onload = function(){
console.log("Onload! document.readyState: " + document.readyState + ", performance.timing.loadEventEnd: " + performance.timing.loadEventEnd);
document.write('<img src="https://techcrunch.com/wp-content/uploads/2017/05/onedrive-illo3.jpg?w=1390&crop=1">');
}


Due to the SetTimeout, the onload message is the first one to occur. The state is complete and loadEventEnd is 0, as expected. But then we write to the document, and the onload finishes. At this point, loadEventEnd is updated, and applying the changes in the document. I'm not sure if readyState needs to change at this point or not, but the loadEventEnd seems to be populated at the correct time.
Ok, shorter code:
document.onreadystatechange = function() {
  if (document.readyState=="complete"){
    alert("Onload! document.readyState: " + document.readyState + ", performance.timing.loadEventEnd: " + performance.timing.loadEventEnd);
    alert(performance.timing.fetchStart);
  }
}

I get document.readyState complete with loadEventEnd not zero and fetchStart is zero.

According to MDN complete is fired before load:
The document and all sub-resources have finished loading. The state indicates that the load event is about to fire.
https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState

It means loadEventEnd has to be still zero at this point.
However fetchStart is zero what is okay.

jsbin.com/wobaduz/1

Comment 8 by dproy@chromium.org, Apr 9 2018

npm@, I see you have already done some digging here. Are you a good owner for this bug? 

Comment 9 by npm@chromium.org, Apr 9 2018

Cc: -npm@chromium.org
Owner: npm@chromium.org
Status: Assigned (was: Unconfirmed)
Ok, I'll assign to myself to dig deeper later.
Indeed, this does not seem to be a problem with Navigation Timing.

The problem here is use of document.write() after the document has completed.

Doing so will delete the current document, create a new one, open it, and write the specified HTML string to it.

The problem is not that loadEventEnd was set while document.readyState is loading. The problem is that after readyState became complete and loadEventEnd was set, the document was deleted and replaced with another. And that new, unrelated, document is in state "loading".

To see:

* Browse to any page and let it finish loading.
* Run 'var myDocEl = document.documentElement;'
* Observe document.readyState === 'complete'
* Observe performance.timing.loadEventEnd is non-zero.
* Run 'document.write("Bye page")'

Then:
* Observe the page has been replaced with the text "Bye page".
* Observe performance.timing.loadEventEnd is unchanged (as it should be, there was not a new navigation).
* Observe document.readyState is now "loading".
* Observe that myDocEl === document.documentElement

As far as I can tell, this is working as it should be and cannot really be improved without breaking web compat.

Comment 11 by npm@chromium.org, May 8 2018

Bug reporter - do you agree with comment #10? Should we close this?
Labels: Needs-Feedback
Does it mean that other browsers behave incorrectly?

Comment 14 by npm@chromium.org, May 10 2018

Which browsers are behaving differently and for which website? I tried opening https://output.jsbin.com/dajiwus/1 on both Firefox and Chrome. In both cases, in the console I got a nonzero performance.timing.loadEventEnd and document.readyState was 'loading'.
I don't see same behavior in FF 60 and MS Edge 1803.
Sorry for the late reply. There have been several examples in this bug so I don't know what you are referring to in #15. I tried what I described in #14 on Firefox 61 and it still shows the same (non-zero loadEventEnd, loading readyState). Could you describe what is behaving differently, similar to how I described in #14?
Ping for more feedback.
This link now works same both in FF and in Chrome: https://output.jsbin.com/dajiwus/1

But this one doesn't: https://output.jsbin.com/dajiwus/1
In FF I don't get alert while in Chrome I do.

Sign in to add a comment