Opened 12 years ago
Closed 11 years ago
#10067 closed bug (notabug)
Firing $.ready on document.readyState === 'interactive' too
Reported by: | skaurus | Owned by: | mikesherov |
---|---|---|---|
Priority: | low | Milestone: | |
Component: | event | Version: | 1.6.2 |
Keywords: | 1.8-discuss | Cc: | |
Blocked by: | Blocking: |
Description (last modified by )
Sorry if dup.
So; imagine situation: FF5, page with ever loading iframe (any other resourse will do I think), jQuery executed after DOMContentLoaded fired (asynchronous loading). On $.bindReady stage document.readyState consistently (a lot of Ctrl+F5) equals to 'interactive', so $.ready wont fire ever, right?
It makes panda sooo sad)
Change History (34)
comment:1 Changed 12 years ago by
Component: | unfiled → event |
---|---|
Milestone: | None → 1.6.3 |
Priority: | undecided → low |
Resolution: | → wontfix |
Status: | new → closed |
comment:2 Changed 12 years ago by
WTF is that?
I provided a number of steps that leads to bug clearly, that's easy to see just looking to $.bindReady source.
The only thing that needs proving is that FF5 can have document.readyState === 'interactive' after DOMContentLoaded fired.
But this is 1) W3C compliant - http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html says 'document.readyState Returns "loading" while the Document is loading, "interactive" once it is finished parsing but still loading sub-resources, and "complete" once it has loaded.' Looks like FF5 adopted this; 2) easily proved.
But instead of investigation or providing technical reasons why current behaviour is right or why it can't be reliably fixed you just give me some marketing. No thanks.
There, have a test case: http://jsfiddle.net/skaurus/xGtUf/1/
comment:3 Changed 12 years ago by
Also Yansky from this stackoverflow question http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded states that he was given information by one of mozilla developers that 'DOMContentLoaded event equates to the document.interactive readystate'
comment:4 Changed 12 years ago by
So, what benefit would jQuery get by adding a lot of extra code to handle something that is "equivalent" to what it already does?
comment:5 Changed 12 years ago by
Don't you see - in testcase jQuery.ready never ever fire? Although DOMContentLoaded did?
Lot of code possibky would be || document.readyState === "interactive"
.
comment:6 Changed 12 years ago by
The only possible way to jQuery to discover that DOMContentLoaded already fired, is check for document.readyState === "complete"
, line 454.
Possibly before FF5 after DOMContentLoaded it indeed always was equal to complete
.
But now after DOMContentLoaded and before onload
it's interactive
, so check for "did DOMContentLoaded already fired?" on line 454 fails, then jQuery setups listeners for DOMContentLoaded
, which will never fire, because it's already fired!
comment:7 Changed 12 years ago by
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
My apologies, my initial resolution was short sighted. Thanks for your patience
comment:10 Changed 12 years ago by
Milestone: | 1.6.3 → 1.7 |
---|---|
Status: | reopened → open |
I am not clear on the case where this would happen. The test case shows something uncommon, loading jQuery after the doc is ready.
comment:11 Changed 12 years ago by
It would happen when jQuery loaded asynchronously, it's a rarity, but it's good practice. Async js loading generaly advised for higher perfomance.
comment:12 Changed 12 years ago by
We've made concessions for RequireJS's needs this has yet to be an issue
comment:13 Changed 12 years ago by
Would this be enough to solve the issue?
from this:
if ( document.readyState === "complete" ) {
to this:
if ( /complete|interactive/.test(document.readyState) ) {
comment:14 Changed 12 years ago by
I believe it would.
Now I use
if (document.readyState === "interactive") jQuery.ready();
after loading my scripts, and it works perfectly.
comment:15 Changed 12 years ago by
This problem shows in practice on Webkit (Safari/Chrome) when DOMContentLoaded has fired before the jQuery.ready() is set up. This makes Webkit wait until window.load before $(document).ready fires.
In practice, in our application, this made $(document).ready fire 5 seconds slower on Safari/Chrome compared to Firefox! So for some sites and apps, this bug can cause serious slowdown while being difficult to debug.
comment:16 Changed 12 years ago by
Correct me if I'm wrong, but simplest patch seems to be:
document.readystate === "complete"
To
document.readystate !== "loading"
Heck, we even save a byte ;). Writing the unit test shouldnt be terrible either.
comment:17 Changed 12 years ago by
Keywords: | 1.8-discuss added |
---|---|
Owner: | set to mikesherov |
Status: | open → assigned |
comment:18 Changed 12 years ago by
ok, so writing the unit test IS terrible. But I making solid progress... early results seem to indicate that the change is fine.
comment:19 Changed 12 years ago by
Milestone: | 1.7 → 1.8 |
---|
comment:20 Changed 12 years ago by
Description: | modified (diff) |
---|
-1, I've been working on this ticket, and tested this in the general case, and it seems to work. It's also one of the simplest changes to make, while very difficult to test. However, I don't know if this would break an expectation that when $.ready fired it meant you could interact with the content of IFRAMEs on the page. Also, it just seems like this is a bit too much of an edge case to change the current behavior.
comment:21 Changed 12 years ago by
+1, We just need to document that the dom of iframes is not guaranteed to be ready in that instance.
comment:22 Changed 12 years ago by
+0, Try to figure if its a bug and handle as such. Too complicated for a vote really.
comment:23 Changed 12 years ago by
Description: | modified (diff) |
---|
+0, Changes in .ready() make me worried when we can't test them easily. So what is the specific benefit to this, and how commonlly is it needed?
comment:24 Changed 12 years ago by
Description: | modified (diff) |
---|
+1, I'm ok with adding interactive if it does not create bugs
comment:25 Changed 12 years ago by
Description: | modified (diff) |
---|
+1, Despite my previous opposition, I'd be interested in giving this a go
comment:26 Changed 11 years ago by
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:27 Changed 11 years ago by
Fix #10067. Create jQuery.quickReady; closes gh-736.
Allows us to get to the ready state sooner by not waiting for iframes to load. If that causes backcompat pain, use jQuery.quickReady = false
as prescribed by your developer.
Changeset: 54fab3174c7844959b374e98b453c048b60de0d0
comment:28 Changed 11 years ago by
We tried, it didn't work. We learned a lot. Like, never listen to skaurus.
comment:29 Changed 11 years ago by
Well, it doesn't work in IE9/IE10, and Android 2.1. Perhaps at a future date, we may be intrepid enough to try this again? I'm a glutton for punishment.
comment:31 Changed 11 years ago by
Does this need to be reopened? #12282 had a regression that reverted the changes made above.
comment:32 Changed 11 years ago by
It's not going to get fixed at least until IE9.0 and IE10 die. So we'll reopen this in 2020 when a fix can be reasonably applied.
comment:33 Changed 11 years ago by
Milestone: | 1.8 |
---|---|
Resolution: | fixed |
Status: | closed → reopened |
comment:34 Changed 11 years ago by
Resolution: | → notabug |
---|---|
Status: | reopened → closed |
jQuery provides a solid, consistent document ready handling system that has been battle tested for the last 5 years on upwards of 24 million websites.