Closed Bug 28293 Opened 25 years ago Closed 16 years ago

scripts with defer attribute not deferred

Categories

(Core :: DOM: Core & HTML, defect, P1)

defect

Tracking

()

VERIFIED FIXED

People

(Reporter: ian.graham, Assigned: sicking)

References

Details

(4 keywords, Whiteboard: [HTML4-18.2.1] [ie-parity] [See comment 26 & 80 for desired behavior])

Attachments

(7 files, 3 obsolete files)

From Bug Helper: User-Agent: Mozilla/5.0 [en-CA] (Windows_98; I) BuildID: 2000012520 The attribute defer="defer" should allow script element content to be deferred execution until after the page is rendered. The example URL demonstrates this using a simple alert() popup which blocks the rendering of the subsequent page, even though the script block is 'deferred'. Steps to Reproduce: See example URL. If defer="defer" is supported, the text of the document should be rendered _before_ you dismiss the alert() popup. If defer is not supported, then you will need to dismiss the alert() before the page is rendered. Notes: Defer was not supported in Nav 4, but is supported in IE 5.x, and I believe IE 4. It is of mixed use, however, as it seems that not all script code can be deferred. I tagged this as normal, but it may in fact be better marked as an enhancement, since it is not a blocker, and there are workarounds possible by moving code to teh end of the document body.
clayton: what's your call on supporting this?
Assignee: rickg → clayton
I wanted to ask expert help from the user perspecive on this issue, so emailed andreww. I asked if users will need this facility and if he had ever needed it in his former life doing JS programming in Professional Services. Andrew replies: Well, there are other ways to defer execution of scripting on load. I've never had a case where I said 'gee, I wish I could not run this until after the page loaded' since I just place the startup code to run on a body.onload handler. But on the other hand, if it's in ECMAscript, it should be supported.. Id say there are bigger fish to fry... -- A final observation, 'defer' is not part of the language standard. And I assume it's not DOM. = C =
Assignee: clayton → rickg
Actually, 'defer' has been part of the HTML standard since HTML 4.0 "strict" (see Section 18.2.1 of the HTML 4.01 spec). The formal description is: "When set, this boolean attribute provides a hint to the user agent that the script is not going to generate any document content (e.g., no "document.write" in javascript) and thus, the user agent can continue parsing and rendering. " I would thus not expect 'defer' to be described in the ECMA spec, since this is processing environment (and not language) issue. However, I do agree with Andrew -- the methods he suggests for deferring execution (body.onload handler, or my lazy favorite of just plopping the script at the end of the body element) can accomplish the same things, however inelegantly (in my example, not Andrew's) Indeed, could one not imagine that <script defer="defer" ...> is essentially equivalent to wrapping the script content in a function, and then running this function from the body.onload handler? If this is so, then it _might_ be easy to implement.
Vidur -- is this part of the DOM spec? If so, the I think we may need to support it.
Assignee: rickg → vidur
Hmm -- trying to reassign to vidur so he can make the call.
The SCRIPT attribute "defer" is a hint and not a mandate to the user agent and should not be used in place of mechanisms such as the one Andrew suggested. Special processing of SCRIPT elements with "defer" set is an RFE that I am currently inclined to mark LATER given the volume of bugs that we currently have.
Status: NEW → RESOLVED
Closed: 25 years ago
Resolution: --- → LATER
Summary: defer attribute not supported on script elements → RFE: defer attribute not supported on script elements
Keywords: verifyme
massive update for QA contact.
QA Contact: petersen → lorca
Being that no one has complained in over 7 months, I'll verify this as LATER.
Status: RESOLVED → VERIFIED
*** Bug 93392 has been marked as a duplicate of this bug. ***
This bug blocks bug 7954, bug 41368. Technically, this is an enhancement but leaving as normal since it is HTML standard and should be fixed. Adding HTML4 keyword. Should we re-open this for re-evaluation?
Blocks: html4.01, robin's
Keywords: verifymehtml4
LATER is deprecated. Setting Target Milestone to "Future" instead.
Status: VERIFIED → REOPENED
Resolution: LATER → ---
Target Milestone: --- → Future
SPAM. HTML Element component deprecated, changing component to Layout. See bug 88132 for details.
Component: HTML Element → Layout
OS: Windows 98 → All
Hardware: PC → All
QA Contact: bugzilla → gerardok
From the HTML 4.01 spec: "defer - When set, this boolean attribute provides a hint to the user agent that the script is not going to generate any document content (e.g., no "document.write" in javascript) and thus, the user agent can continue parsing and rendering."
QA Contact: gerardok → moied
Whiteboard: [HTML4-18.2.1]
Keywords: perf
so I'm reading this bug... and everyone is assuming that "defer" means "execute once all the content is rendered". I see nothing to support that interpretation. To me, it says "this script has nothing to do with content rendering and they can be done in any order". In particular, there is no reason not to render while the script is coming in, execute it once it comes in off the network, then continue rendering. Or am I missing something?
The DTD for the "defer" attribute also has the comment "UA may defer execution of script". Support is optional. It might be desirable to implement deferred execution to improve rendering speed on pages with many JavaScript functions in a <script defer>. However, I agree with Christopher; this should have severity set to "enhancement". In any case, changing misleading summary to "scripts with defer attribute not deferred".
Summary: RFE: defer attribute not supported on script elements → RFE: scripts with defer attribute not deferred
So how does IE implement this? In particular: 1) <script src="foo" defer> <script src="bar"> Can the second script access things defined in the first one? 2) <script src="foo" defer> <script src="bar" defer> Is the second script guaranteed to load after the first one? (in IE; I realize that the HTML spec says absolutely nothing here)
Microsoft's documentation of the "defer" attribute (http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/defer.asp) makes no guarantees. The following produces no output with IE6 under WinXP: <script defer> var test = "<p>This is a test.<\/p>"; </script> <script> document.write(test); </script>
That produces no output or that throws a "test is not defined" error?
Also, it does not matter what the documentation says; what matters is what the actual behavior is.... :(
No output and a "'test' is undefined" error popup, if script error notification is turned on.
Hi, The defer attribute can be an extremely performance enhancing feature, to the extent where in relevant cases Mozilla at present performs very slow compared with IE. Consider this HTML code: <SCRIPT> function init(){ }// function </SCRIPT> <SCRIPT src=someurl.js defer> <SCRIPT> document.write('<FRAMESET rows="50%,50%" onLoad=init()>'); document.write('<FRAME src="some_otherurl_1">'); document.write('<FRAME src="some_otherurl_2">'); document.write('</FRAMESET>); </SCRIPT> The above works beautifully in IE but turns out to be very ugly with Mozilla. The deferred script holds up the writing of the frameset until it is actually 1) loaded over the network, 2) compiled and 3) initialised. This creates a bad performance degradation. The page literally hangs for quite a while. Please consider that framesets by themselves already have a built-in disadvantage. I would tend to give this a higher priority and some milestone because I think it is a commonly used feature that makes Mozilla look ugly in comparison with IE.
> I think it is a commonly used feature Can you back that up with hard numbers? Preferably on top100 or top500 sites? That would really make it easier to convince people to prioritize this bug more highly, you know... This bug still needs an answer to question #2 in comment 16 (many thanks to Robin for answering question #1).
Sorry, I can't provide any info about other sites. My guess was derived from news post frequencey and the fact that IE4 already supports this. And the pseudo testcase should serve as a good basis for discussion. I am normally embedding scripts so this is not a great issue for myself - just had a case where IE's stunning performance highlighted the potential of this trick. Re question 2) I would not rely on any sequence even if a test would prove my trivial guess that they are executed in the order they are written. Of course I would prefer it this way because otherwise programming might get very tricky in such cases.
Attached file Testcase for this bug... (obsolete) (deleted) —
Attached file Real testcase for this bug (obsolete) (deleted) —
Attachment #90759 - Attachment is obsolete: true
Since some people seem to not understand the concept explained in comment #19.... I finally got my hands on IE6/Windows and tested with the attached testcase. The behavior seems to be as follows: 1) First load any non-defer scripts 2) Then load inline defer scripts 3) Then load external defer scripts with each set of loads happening in document order. Any corrections to this analysis would be most welcome (timeouts of arbitrary length between 1 and 99 seconds can be gotten by changing the source in the obvious way). I cannot for the life of me figure out why #2 and #3 are separate groups of loads (three cheers for lack of rhyme or reason!), but we'd have to do it that way as well as a result... Doing that and at the same time getting the document order thing right will be quite a bit of work. I'd have preferred if IE did not do that (programming would _not_ be tricky -- that's what the onload event is for!), since then I'd have had a chance of fixing this bug in some sort of reasonable amount of time.... <sigh>.
There are scenarios where a JavaScript developer might get into big trouble if not careful and if a group of scripts are not compiled and initialised in order. This happens if such scripts are referencing each others' 1) functions 2) values. Note that they get ready in that order. Are you sure that an onload event is always a guarantee that all scripts have been compiled and initialised? Which onload event would you use to manage a series of scripts residing in the head section of a framesetting document? Sure the frameset onload could be used for that but that's way too late. I have a faily interesting testcase where onload events seem useless under some conditions. I can attach that if you like.
> This happens if such scripts are referencing each others' 1) functions 2) > values. This is already broken by the fact that inline defer scripts and external defer scripts load "out of order".... In any case, the desired behavior is that described in comment 26, unless I'm missing something about IE's implementation.
Whiteboard: [HTML4-18.2.1] → [HTML4-18.2.1] See comment 26 for desired behavior
I don't understand why it matters so much how IE has implemented it. Shouldn't we just follow the spec?
Because the spec says absolutely nothing about any of this. It just vaguely mumbles something about continuing rendering. In particular, any answers to the questions in comment 16 are perfectly fine per the spec. So given that we can do whatever we want, the obvious thing to do is to not break pages that _do_ use this attribute and depend on IE's ordering, I would think.
You said yourself that IEs order makes no sense. Given that we can do whatever we want, the obvious thing to do is to do at as simple as possible IMO. Sites that depend on IEs loading order are heavily brain-damaged.
"as simple as possible" would be loading in the order in which we get the data... this is precisely the order bht@actrix.gen.nz objects to. Sites that are depending on this are in no way brain-damaged, imo. The simple fact is that this is in HTML4 is because IE4 implemented it and MS prevailed on the HTML WG to include it after that.... So the "standard" behavior is that of IE4, in essense.
Alias: defer
Just a note from the perspective of a Web Application builder vs a web site for the masses. We are currently running loadtests against our web app and web app server. We have found that linking js files causes the pages to load them serially, halting downloads and giving us perf spikes especially on low bandwidth connections. Right now opening a loan loads something like 20 different .js files. If we can't load them concurrently and we have a 180ms latency, that adds up to 3.6 seconds just in latency for the js files!!! Not counting the additional time to download the .htm and .gif files and finally the 3 round trips we have to make to the surrogate! All of this adds up to a 10 second or more loan open time even on a fat pipe like a T1 if the latency is high (and 180ms is not that high!!!) If the defer tag or similar feature would just allow the files to load concurrently, our performance would rock. :-) I don't pretend to understand the loading order or it's complexity, but if anyone could add this feature with the defer tag or perhaps point me to a solution to allow concurrent downloads without having to have all the scripts inline in a page, that'd be great. Also, just to expound upon "lack of rhyme or reason". Mozilla seems to load frames and framesets in the order listed in code. IE on the other hand, loads them from the innermost child up to the parent, which causes all sorts of issues when trying to control round trips and load orders on the client. Please don't follow the IE way on the defer. Moz already has a much better load order than IE I'd hate to see it get thrown away with the implementation of DEFER
taking. I'll try to hack on this in the long term.
Assignee: vidur → bzbarsky
Status: REOPENED → NEW
Target Milestone: Future → mozilla1.6alpha
interesting bug... bz: is it possible to just build up two queues of deferred inline and extern scripts, store these in the document (or whereever), and then before onLoad handlers fire, pull down each script and execute? probably i'm overlooking something that makes this difficult :-/
Well, there's no win there... The idea, as I see it, is that you kick off an async load as soon as you see the <script> tag but you delay evaluation of the resulting content till onload. If you just wait till onload to start synchronosuly fetching stuff, you don't reduce the page load time.... There are various simple conceptual schemes to do this -- the devil is in the details. ;)
bz: ic... i guess i misunderstood then. i thought the problem was sync loading of deferable scripts blocking sync loading of non-deferable scripts. if that were the only problem then simple reordering would be enough, right? also, you might want to watch out for the particularly nasty case of the same extern script being loaded twice on a page (not that that should be common, but maybe some misconfigured page authoring tool), one defered and one not defered. if you encountered the defered one first and then say suspended it via nsIRequest::suspend, then second request would get blocked waiting for access to the cache (only one writer per entry at a time in the cache). using suspend would not be ideal for this reason as well as others. the suspended JS channel could not be used to download other things, for example.
Good point; I guess the right way to do it is to load the script completely and then just defer evaluation till later.
Attached file Test of defer attribute (deleted) —
Boris' attachment attempted (and failed) to load an external file. The file was missing and the attachment didn't work. Why do we need defer? Defer can be used as a performance-enhancer: http://msdn.microsoft.com/workshop/author/perf/perftips.asp#DEFER_Your_Scripts http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/defer.asp As for top 100 sites, I've seen defer used on microsoft.com before. Defer definitely isn't used as often as it could/should be. It's often overlooked and not widely known.
Attachment #90760 - Attachment is obsolete: true
Keywords: testcase
Target Milestone: mozilla1.6alpha → mozilla1.7alpha
In my web applications, I retrieve source (mixed html/scripts) from the server using xmlhttp and then insert these into designated DIV tags. I don't want to use IFRAMES for various reasons. This works well in IE but not in Mozilla. In Mozilla it just doesn't recognize any scripts that is included through this method. Sample program (from M$ site): <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>InsertScript Sample</title> <script> function insertScript() { var sHTML="<input type=button onclick=" + "go2()" + " value='Click Me'><BR>"; var sScript="<SCRIPT DEFER>"; sScript = sScript + "function go2(){ alert('Hello from inserted script.') }"; sScript = sScript + "</SCRIPT" + ">"; var a = document.getElementById("ScriptDiv"); a.innerHTML = sHTML + sScript; } </SCRIPT> </head> <body onload="insertScript()"> <blockquote CLASS="body"> <h1>Insert Script Sample</h1> <p>This example uses the <b>innerHTML</b> property to insert script into the page.</p> <div ID=ScriptDiv></div> </blockquote> </body> </html>
Pieter, see bug 147581. Does IE evaluate scripts in innerHTML only if they have "defer" set or something?
Target Milestone: mozilla1.7alpha → Future
Note to self: it seems IE's behavior is just wacko (see http://www.websiteoptimization.com/speed/tweak/defer/). Probably best to just ignore it.
Severity: normal → enhancement
QA Contact: moied → nobody
Summary: RFE: scripts with defer attribute not deferred → scripts with defer attribute not deferred
maybe a stupid question and sorry for the bugspam if I am wrong. If this is in the standard specs, why is this bug then marked as an enhancement?
Have you actually read the spec, perhaps? This attribute tells the UA that it may do something if it feels like it. It does not require doing anything.
One other issue that shaver mentioned on IRC today: what should happen if the DOM is modified on a page with defer scripts? That is, if a deferred <script> is removed from the DOM before the script has executed, should it still execute when it normally would have? On a separate issue, shaver says that as he recalls deferred scripts ran the first time any script ran after they were loaded (including <script> and on* handlers). This also needs testing....
Keywords: qawanted
Frankly I recommend WONTFIX. Authors can get reliable "defer" behaviour using document load event listeners. There doesn't seem to be much point in having an attribute to do this. I'm tempted to propose just deprecating the attribute in the WHATWG drafts.
Ian, see comment 36, where I already addressed that suggestion once....
Sorry, missed that. So the idea here is by implementing this attribute, we would get a performance win on pages that fetch remote scripts and mark them "defer"? Do we really care enough? It doesn't seem like there are that many such pages. I can't think of a single time I've seen it in the wild. I'd have thought the gain in implementing this would be outweighed by the cost of the increased complexity and footprint of the codebase (even if the difference was minute...).
There's a reason this hasn't been a top implementation priority... ;)
... ditto (what Boris said) ... There isn't much value in making this work.... IMO there are many more useful things to work on.
(In reply to comment #46) > Frankly I recommend WONTFIX. Authors can get reliable "defer" behaviour using > document load event listeners. There doesn't seem to be much point in having an > attribute to do this. I'm tempted to propose just deprecating the attribute in > the WHATWG drafts. I will do my best to explain. A developer could use "load" event listener on the window and create a script element. if(window.addEventListener) window.addEventListener("load", addScript, false); else if(window.attachEvent) window.attachEvent("load", addScript); But then we developers have to write more code and that would take away from performance, real and perceived. It would be more convenient for a developer to use the defer attribute then to write extra code to simulate the effect. Although I admit that defer is not used often enough, it a is useful feature, nonetheless. Many other dom features that are supported by Mozilla are useful, but not used because of lack of support in IE. This bug is just a role reversal, with IE being the compliant browser for this feature. Boris -> ...if a deferred <script> is removed from the DOM before the script has executed, should it still execute when it normally would have? No. Once a script has been removed, it cannot be interpreted (a script must be interpreted before it is executed). The script element and it's functions should no longer be available.
> No. Once a script has been removed, it cannot be interpreted Is this IE's behavior in the scenario in question? What about deferred scripts that are executed earlier removing deferred scripts that were going to execute right after them? Finally, what about having two inline defer scripts, where the first modifies the text in the second. What gets executed? The text that was there when the script was first parsed, or the new text? (These are all questions about what IE does, not what people want to happen.)
This is a demo to show that IE doesn't wait till the end to process deferred scripts - it only waits till the non deferred scripts are done. OK, everybody already knew that (well, I hope not, because it's not true), but I thought it would be nice to isolate it so that there's no confusion on this point: defer is not to be used to avoid race conditions with page parsing. Further attachments intend to show the generalization of what this page demos. Csaba Gabor from Vienna
Firefox won't emulate IE perfectly, I hope, if it puts in defer support. This weird IE bug will also be a good test case to make sure Firefox handles a deferred javascript: protocol. Seems that IE has a conflict modifying the DOM if there's an earlier javascript: protocol. This came about because the javascript protocol is useful for constructing self contained test cases. Fortunately, IE had no problems when setting the src of script elements to javascript: protocols via the DOM. Here is the code. To eliminate the IE bug, you must either remove the defer or comment out the document.getElementById line: <html><head><title>Defer testing</title> <script type='text/javascript' defer id=scriptDeferredSrc1 src='javascript:"alert(&#39;script loaded&#39;)"'> </script> </head><body> <table border id=table><tr><td>&nbsp;</td></tr></table> <script type='text/javascript' id=scriptImmediateInline> var one=2; // dummy line document.getElementById('table').rows[0].cells[0].innerHTML = "Inline immediate script has loaded"; </script> </body> </html>
appendInfo('immediate SRC=... loaded') This is a one line external .js file needed for the MainEvent attachment to answer Boris' questions.
Attached file MainEvent - Answers for Boris (deleted) —
Firstly, the basic algorithm mentioned in comment 26 (and then comment 42) is incorrect. Closer seems to be: 1. Parse nondeferred scripts till an external or the last script is encountered 2. Fetch and execute all scripts encountered to that point. Continue with 1. Script elements are placed into the DOM when they are encounterd going through 1. and 2. The fetching is asychronous (you can't know when files are going to come in), but it explains the earlier conjecture: deferred inline files should always come back before external files. If you have InlineImmediate, InlineDeferred, InlineImmediate2 then when the first one is hit, there will only be a script element from InlineImmediate and then when InlineImmediate2 is hit, you have a reference to all three. To answer the three questions in comment 52: 1. If you nuke the deferred script element before it executes, it won't execute (see Inline Deferred 6 - this causes Firefox an error, by the way). 2. Um, same story except it's not as safe, because all the deferred scripts in a block (between external immediates) are fetched asynchronously. Now presumably(!), the inline deferred scripts in this block will be returned in file order. 3. This is more interesting. First off, I tried modifying the .src and there was no problem with that. If the src is modified before the script is executed, the new .src is used. A script can similarly modify is own .src. Danny Goodman says that modifying .text in IE will do it but won't have any effect. Ha ha. In my IE it's exactly the opposite - you get double. Seems like changing the text on any script element will actually execute the script you're trying to stuff whether or not the element is already loaded. So in the case of a deferred inline script, you get one execution on account of changing the text and one on account of the deferred script still needs to execute. That's just wrong. Other oddities. If you open the attachment in Firefox, then the DeferredInline3 script doesn't like either of the first two things it has to do: deleting DeferredInline3 or modifying the text of DeferredInline6 because those items are not yet in the DOM. Firefox doesn't show the 10th script name (DeferredInline6) - not sure what's happening there. Modifying the defer property to false did not seem to change its status as far as IE was concerned, despite what Danny Goodman claimed about it being a read write property. By the way, how come you can't get the contents of an external (src=...) SCRIPT element via the DOM? My opinion: It's important to implement defer because it will gain a noticable speedup on some sites. However, subject to the discussion above, noone seems to be using the exact order that deferred script arrive in. The point is that even if what is implemented is different from Microsoft, the number of sites that will break as a result ought to be miniscule because chances are small that people are making use of unpublished, unguaranteed arrival rates of the the various deferred scripts. Therefore, any reasonable implementation will be reasonable. Furthermore, I would argue that Microsoft's implementation is not as efficient as it might be. For example, suppose that an alert box appears in the first inline immediate script. For this, they would suspend bringing in all other scripts (actually, I'm not sure I tested that so sorry if I'm messing up this argument)? What I would do: Defer means Asychronous (and the only thing asynchronous scripts can count on is that they get executed before the document.onLoad fires). As you go through the page and encounter a script, it gets categorized as Sychronous (immediate) vs. Asychronous (defer) and added as an element to the DOM (in encountered order). This is consistent with IE. If it's asychronous, start the process to 'bring the file in' (though not execute it). If it's sychronous inline execute it. If it's synchronous external, (1) start off a process to get the file, and (2) continue parsing so as to identify any other files that need to be brought in, and (3) while there is time, execute any waiting deferred script. I've actually not used defer in practise, but it would be nice if some of the things that were asked in testing with IE (especially being able to set src or text) were possible with Firefox (and more importantly, using the current <Base href=...> value) Finally, I mention one other thing. I went to the site in comment 42 and did their little test. I am getting Inline Body AFTER Inline Body Deferred EACH TIME. That's the reason I said 'Closer seems to be' at the very beginning, because what I proposed doesn't match observed behaviour on their site either. It does, however, match the proposed algorithm that I gave at the end here. I think that while they are waiting on a sychronous external request to come through, they start taking care of backed up deferred scripts and when they run out of those they continue forward bringing in (and executing) deferred scripts - since (to my mind) they're asychronous, that makes it OK to bring them in early (as long as there's no sychronous script ready to be executed). Csaba Gabor from Vienna
(In reply to comment #56) > 1. Parse nondeferred scripts till an external or the last script is > encountered What does "last" mean here, exactly? There's no good way to determine this that I can see... > but it explains the earlier conjecture: deferred inline files should > always come back before external files. Why? If the external fetch is async, it could come back before the inline script is even parsed. Or are you saying that IE defers not just script execution but also fetching the script? > If you have InlineImmediate, InlineDeferred, InlineImmediate2 then when the > first one is hit, there will only be a script element from InlineImmediate and > then when InlineImmediate2 is hit, you have a reference to all three. It's not clear to me what this is saying.... > 2. Um, same story except it's not as safe, because all the deferred scripts > in a block (between external immediates) are fetched asynchronously. So they can execute in non-document order? (Note that that's not what earlier testing showed.....) > the number of sites that will break as a result ought to be miniscule Only because the number of sites using "defer" is miniscule... > because chances are small > that people are making use of unpublished, unguaranteed arrival rates of the > the various deferred scripts. This is the web. Trust me, people are depending on the exact undocumented behavior... > If it's synchronous external, (1) start > off a process to get the file, and (2) continue parsing No can do -- synch external scripts can do document.write(), which means no parsing can happen till after that script has executed. Your testcases would be a lot easier to read if they would clearly indicate, when the testcase is loaded, which order the scripts executed in (and if the comments in the testcase would clearly indicate which order the scripts execute in in IE).
A good online test case is at: http://www.websiteoptimization.com/speed/tweak/defer/test/ It would have been better if it had "onload" in the game too. Am I right that even when deferred, deferred scripts should be loaded before "onload" still? It makes a lot of sense that way, and not much otherwise.
Mmm.... that testcase's image shows an order different from that which was conjectured earlier in this bug. Is that order correct? That is, is there really the wackiness with inline deferred scripts that that testcase shows?
As per my earlier comment, "defer" won't be in WHATWG draft (unless someone argues for its return). It is very rarely used. I suggest WONTFIX. I don't think any improvement we would get would justify the implementation cost and the increased codebase complexity.
I agree with Ian -- WONTFIX is best. This really provides no compelling benefits....
i'm sad to see that DEFER still isn't supported in Moz/FF. i had a problem with some HTML and "JavaScript" that needed to be moved from a hidden frame into a web-apps main frame via innerHTML. <script> blocks won't get executed this way neither in IE nor Moz. but in IE it can be achieved with a DEFER set. see http://msdn.microsoft.com/workshop/samples/author/dhtml/refs/insertScript_2.htm as an example. i found a workaround for my actual problem but that ugly ".eval()" in firefox i had to use looks awful compared to the deferred script in IE :(
If you createElement() a new <script> element and insert the script into that then insert the element into the document, that should work.
(Having said that I can't really see any real use case for doing that.)
Not getting to this any time in the foreseeable future (this year, at least).
Assignee: bzbarsky → nobody
Priority: P3 → --
Target Milestone: Future → ---
A very common (f not the most common) use is to make pages appear on the screen faster. Without this working, Mozilla/Firefox just performs badly and users won't know why. It was suggested to move the script to the end of the document. Not possible with <frameset>. The dilemma is that browsers ignore all scripts after <frameset>. Delaying a frameset is the worst thing to do as it already suffers from delays due its own nature.
Were a content management/provider for people wishing to personalize messaging to their users. The defer attribute is used in our case to make sure that our remote snippet does not affect user's experience when loading our customer's page while our servers are slow or down. With IE, this works extremely well since the page will render weather or not our servers are responding adequately. It would be great to have the same robustness with FF.
defer is the part of HTML 4.01 specification so Moz should start support at last! Here is the life example of 'defer' use for me: I have the web page which loads several large js files with pure data via script.setAttribute("src", src); script.setAttribute("defer", true); document.body.appendChild(script); and for the same page I'am catching onload event. The problem is: the onload event fires only after all scripts finished loading, while I need it just after doc. body finished loading. 'defer' helps me greatly in IE, but not in Mozilla!
*** Bug 306199 has been marked as a duplicate of this bug. ***
I've read the conversation on this topic with the main idea that the implementation of 'defer' is a complex task. I'am failing to understand why. From my view it is as much easy as the original implementation of, say, async "onfocus" event firing. The internal async event, for ex named "__internal_execute_loaded_script" should be posted to internal window event message queue after the .js file is fully loaded and handled the same way, say, the async "onfocus" event are handled and dispatched to the user space if asked to.
*** Bug 311276 has been marked as a duplicate of this bug. ***
One of the questions put forth by Boris is how defer actually works in IE. From what I remember of tests I did several months back, defer in the <head> section is completely ignored and only has effect when it appears in the <body> section. Go figure. Csaba Gabor from Vienna
This is not really true. At least in IE 6.0 scripts in <head> are deferred. I will post an example soon
Harrumph. This is what happens when one doesn't test one's statements thoroughly before posting. The following demonstrates that Ivan in comment 74 is correct: <html><head><title>Defer test</title> <script defer type='text/javascript' src="javascript:'alert(&quot;script 1&quot;)'"></script> </head> <body> <script type='text/javascript' src="javascript:'alert(&quot;script 2&quot;)'"></script> </body> </html> The above page will show script 2 first in my IE6 on Win XP Pro before showing script 1. Of course, FF shows script 1 first. At the same time, I'm sure there was some distinction between defer in the head vs. body when I was conducting my tests. That'll take some time to review, but if I figure it out I'll post back.
*** Bug 338806 has been marked as a duplicate of this bug. ***
FYI: based on author feedback, I plan to reverse engineer this and spec it in the WHATWG spec in due course.
See also bug 364315, "Speculatively load referenced files while 'real' parsing is blocked on a <script src=> load". That would solve some of the same latency issues on sites that don't or can't use the defer attribute.
Steps to reproduce: <script type="text/javascript" defer> function ha8validate(p5event) { return true } document.forms[0].onsubmit = ha8validate </script> This script fails because document.forms[0] does not exist yet. It would exist if the script were properly deferred (and, of course, if the body contains a form).
WHATWG spec is updated, by the way, and defines how this should work now, in extreme detail. Let me know if you see any problems with it.
'blocking1.9=?': As I guess it's too late for 1.9.0.0, I'm looking for 'wanted1.9.0.x' or 'wanted‑next'...
Severity: enhancement → normal
Flags: blocking1.9?
Keywords: qawanted
QA Contact: nobody → layout
Whiteboard: [HTML4-18.2.1] See comment 26 for desired behavior → [HTML4-18.2.1] [ie-parity] [See comment 26 & 80 for desired behavior]
Not blocking 1.9. Really too late.
Flags: blocking1.9? → blocking1.9-
Flags: wanted1.9.1?
Yes, definitely wanted for 1.9.1 Every millisecond you can save is good to save, and that's also for the sake of those who care to program correctly (their scripts).
Ok. Getting this on the list for 1.9.1. Assigning to Sicking. Apparently this is only about a days work for a decent win here.
Assignee: nobody → jonas
Flags: wanted1.9.1? → wanted1.9.1+
Priority: -- → P1
Hixie do you have more detailed stats of the current use of defer tag: http://code.google.com/webstats/2005-12/scripting.html On the web?
Assignee: jonas → nobody
Component: Layout → DOM: HTML
QA Contact: layout → general
Assignee: nobody → jonas
Attached patch Patch to fix (obsolete) (deleted) — Splinter Review
Attachment #331023 - Flags: superreview?(jst)
Attachment #331023 - Flags: review?(jst)
Attached patch Slightly better tests (deleted) — Splinter Review
This also tests that deferred scripts execute properly after the document has finished loading. All the code is exactly the same as previous patch, only the tests have changed.
Attachment #331023 - Attachment is obsolete: true
Attachment #331277 - Flags: superreview?(jst)
Attachment #331277 - Flags: review?(jst)
Attachment #331023 - Flags: superreview?(jst)
Attachment #331023 - Flags: review?(jst)
Comment on attachment 331277 [details] [diff] [review] Slightly better tests - In test_bug28293.html: +function done() { + is(res, "ABCDEFGHIJ1abcdefM2g34hi", "scripts executed in the wrong order"); This test should result in something cooler like "One ring to rule them all, ...", I mean, really. :) r+sr=jst
Attachment #331277 - Flags: superreview?(jst)
Attachment #331277 - Flags: superreview+
Attachment #331277 - Flags: review?(jst)
Attachment #331277 - Flags: review+
Component: DOM: HTML → DOM: Core & HTML
Oooh exciting, a patch. When applied, will the attached test still give "Pass?" in a popup?
(In reply to comment #89) > Created an attachment (id=332483) [details] > When applied, will the attached test still give "Pass?" in a popup? No it doesn't. Why should it? DOMContentLoaded is dispatched right after the parsing has finished. Though, seems like the behavior could be changed pretty easily so that deferred scripts are executed right before DOMContentLoaded.
Thought it might not. Asked, as both are currently used in pages to delay execution of scripts. General method is giving IE a seperate defered script block with conditional comments, but I've seen pages with behaviour that reduces to that test. Don't have particularly strong feelings about the resolution, just thought it's a potential area of change that people should be aware of.
This bug is fixed fwiw, the patch is checked in. Yes, I decided to dispatch the DOMContentLoaded event before running deferred scripts, couldn't really think of a good reason either way so I just picked one. Please file a separate bug if you think it change be changed.
Status: NEW → RESOLVED
Closed: 25 years ago16 years ago
Resolution: --- → FIXED
For devmo: Usually when we parse a <script src="..."> element we immediately stop parsing until the script is fully loaded and executed. The result is that in something like <script src="A.js"> <script src="B.js"> <script src="C.js"> We don't even start loading "B.js" until A is fully loaded and executed. Same for C which doesn't start loading until A, then B, has loaded and executed. The reason we have to wait is that when the script executes it might expect just the part of the page that is before the <script> to have loaded, and nothing after, especially if the script does calls document.write, it might expect the new content to be inserted right after the <script>. By setting the defer attribute the page lets us know that the script does not need to execute immediately. Instead the script will execute once the page is fully done parsing. So in a page like: <html> <head> <script src="A.js" defer> <script src="B.js" defer> <script src="C.js" defer> </head> <body> ... page content here ... </body> </html> We'll start the loads for A, B, and C in parallel and then execute them after parsing the </html> tag. You can combine both deferred, and normal scripts. As with normal scripts, deferred scripts always execute in the order they appear in the markup, no matter which order they finish loading. And like with normal scripts, onload won't fire until all deferred scripts have finished loading and executing.
Keywords: dev-doc-needed
Is there a DOMContentLoaded timing bug out of this? Seems like we fire DOMContentLoaded after a trailing non-defer <script src=""> was executed, not after we finished parsing the </script> even if it were the last thing in the document. Should they be the same way?
I would think that would have always been the case. Non-deferred scripts will halt the parser which means that we won't send the DidBuildModel that lets us know that we've reached the end. If you think we should change this (which i'm personally not convinced of) it would be an orthogonal bug.
Dcumented here: http://developer.mozilla.org/En/HTML/Element/Script Feel free to add details if needed.
verified this is working as advertised: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b1) Gecko/20081007 Firefox/3.1b1
Status: RESOLVED → VERIFIED
Depends on: 469751
I do not understand the idea of a fixed bug depending on a new bug. Perhaps it is just me. Shouldn’t the bug be reopened?
That is the standard convention here since Bugzilla doesn't have a good mechanism for marking bugs as regressions from other bugs. As a result, regressions are marked blocking the original bug under the logic that if this bug were to ever land on a new branch, it would require the fixes from those regression bugs to go in with it. If you have any other questions, please ask privately so as to avoid off-topic conversation in this bug.
It was mentioned that DOMContentLoaded is fired before deferred scripts. I believe many of us are going to start using defer as an alternative to DOMContentLoaded, so firing the event afterwards requires giving us some way to detect if the script was actually deferred. What I currently do is include a script with defer, and the first few lines of that script are: if (addEventListener) addEventListener("DCL", load_complete) else if (IE) load_complete; // since defer in IE is equivalent to DCL else onload = load_complete; // fallback for other browsers It's a fairly clean, simple solution. With DCL dispatched before a deferred script is processed in 3.1, this prevents the script from ever firing load_complete. I certainly wouldn't mind changing the second line to read if (IE || defer.supported), but I'm not aware of how to detect defer support in 3.1.
(In reply to comment #100) > It was mentioned that DOMContentLoaded is fired before deferred scripts. I > believe many of us are going to start using defer as an alternative to > DOMContentLoaded, so firing the event afterwards requires giving us some way to > detect if the script was actually deferred. Michael, would you mind filing a new bug about that (i.e. with the summary "<script defer> scripts run after DOMContentLoaded"), and mentioning the number here? We should track that separately.
(I don't know enough about this code to say whether would be easy to fix, or whether we would even want to, but a new bug report is easier to bring attention to than a comment in a closed bug.)
Blocks: 474392
It seems you do not need to check whether defer is supported, you just need to check whether the current script is being deferred. You can achieve that along these lines: <SCRIPT TYPE="text/javascript" DEFER><!-- alert(is_deferred) //--></SCRIPT ><SCRIPT TYPE="text/javascript" ><!-- is_deferred = true //--></SCRIPT >
Flags: blocking1.9.2?
Seems broken in Firefox 3.6 beta 5. "Pass?" is given in popup. It seems with the patch applied it shouldn't. (In reply to comment #90) > (In reply to comment #89) > > Created an attachment (id=332483) [details] [details] > > When applied, will the attached test still give "Pass?" in a popup? > No it doesn't. Why should it? DOMContentLoaded is dispatched right after > the parsing has finished. Though, seems like the behavior could be > changed pretty easily so that deferred scripts are executed right before > DOMContentLoaded.
oops missed bug#518104
Flags: blocking1.9.2?
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: