- From: Bruno Racineux <bruno@hexanet.net>
- Date: Tue, 09 Jul 2013 18:31:41 -0700
- To: Ian Hickson <ian@hixie.ch>, <whatwg@whatwg.org>, <getify@gmail.com>, <jaffathecake@gmail.com>, <travis.leithead@microsoft.com>
I just joined the list and glad this subject is brought up. I have been wrestling pretty hard with script loading issues lately. I'd say that having the browser manage script interdependency is probably a bad and cumbersome way to solve these issues. I'll try to explain, talk about the defer approach, as well as critical IE bugs that relate to this very subject. I think one of the reason that people may ask for this Interdependency feature, is due to the weakness of the platform they use, its plugins or the poor management of such script (with often poorly conceived plugins not takign dependency into account), which too often has the approach of loading all scripts at all times regardless of the page context. What's important to keep in mind, is that if you must have the browser managing the interdependency, by association, you also have to manage it at the app/platform level properly in the first place. Which seems awfully redundant... And would probably lead to more page bloat or bad programming habits. As Kyle Simpson said, the primary motivation here is performance. Putting scripts at the bottom, while preserving the scripts order has performance drawbacks. And 'async', while good for independent scripts such as social media apis, is not really a good tools for dependency management. My main issue against using external script loaders like LABjs and others, has always been that if the browser must download a script first, before starting to download the dependencies. It presents a drawback already, for delayed the scripts by the script loader's latency and download time (at least for the first uncached page load) similarly to having scripts at the bottoms. What we truly want is keep the order while loading script in a non-blocking way. Why not simply load all such scripts early in the <head> with 'defer', which preserves the dependency order as determined by your app. Using 'defer' in head scripts is actually a very good way to preserve script order with non-blocking scripts. And by loading the scripts very early in the <head>, the possibility of a incurred significant delay of DOMContentLoaded, for an eventual large script not yet downloaded, is minimal to none. In that sense, I think that too much focus has been placed on 'async', with 'defer' having been extremely overlooked as such an adequate method to non-blocking script loading with dependencies preserved. 'defer' after all, is partly designed to guarantees that scripts execute in the order they were specified and be delayed until document.readyState = interactive; I sadly know there is a big hurdle for using 'defer' right now with interdependencies, mainly with this IE9 bug http://bugs.jquery.com/ticket/11310 Debunked in further details here (coincidentally, in part by Kyle Simpson): https://github.com/h5bp/lazyweb-requests/issues/42 And may I get into further IE hate when it comes to the 'interactive' state inconsistencies, by pointing to this very recent bug report I've had to file: https://connect.microsoft.com/IE/feedback/details/792880/document-readystat e-interactive-firing-too-early-misfiring-in-ie11-9-and-10 Or should I beg the question, as to why it took my initiative yesterday after almost a year of the problem being reported by others on github in multiple occasions, to have this looked at so that IE11's final release get it right, or not, who knows... This problem exist since IE7! Is that really the best Microsoft can do? There is something really wrong with the fixing process here. That, or too big of a disconnect between those who test and those who are supposed to fix things. Or it is that developers are too fed up with those bugs, having to find ways around them, to find the energy to report them appropriately? Thankfully, the IE7-9 'defer' bug is has been fixed in IE10. Yet it's likely postponing proper use of 'defer' for another what? 5 years?. Thanks to Microsoft once again for holding the internet back and make our life harder? Is that all we can come up with? I would actually advocate to petition Microsoft to release patches for IE8, IE9 and IE10 for these particular stupid overlooked bugs, which some days honestly make me want to kill myself. I understand that in some areas, older browsers cannot add or remove features to the same major release for good reasons. But it's a real problem if bugs of this kind ( which wouldn't break any site if fixed now), cannot be fixed on older browsers using regular Windows updates. The idea that a browser is set in stone on release, and cannot be touched become a real issue to progress. Aren't those two particular bugs good example of thing that should be fixed and applied along security patches? And not have to wait 5 to 10 years coping with buggy browsers for no good reasons I can think of. I would also strongly favor restoring the previous spec portion of 'defer' which allow to have defer on inline script blocks (i.e. if the src attribute is not present). I don't know why this html4 functionality was removed from html5? I see use cases which would give much more flexibility with dependencies (such as putting jquery on 'defer' in the head with inline 'defer' jquery functions) and possibly even improving performance significantly. And I am not saying that 'defer' is the only answer to script loading, but at least if it worked across browser we would be here in this poor pitiful state of not being able to use features that date back to HTML4 and should be working on all browsers properly by now, to do such simple things as deferring jQuery scripts. Back to the initial question from my rant. While there is a use case for not downloading or executing scripts until needed, this can somewhat already be dealt with using ajax or the post-eval method google uses. Or perhaps this script execution hold could be an ajax only solution, with a no-execute-yet property and a pure javascript behavior, rather than also implicate DOM attributes into this. On 7/9/13 12:39 PM, "Ian Hickson" <ian@hixie.ch> wrote: > >A topic that regularly comes up is script loading. > >I sent an e-mail responding to related feedback last year, though it >didn't get any replies to the script loading parts of it: > > >http://lists.w3.org/Archives/Public/public-whatwg-archive/2012Dec/0221.htm >l > >It seems that people want something that: > > - Lets them download scripts but not execute them until needed. > - Lets them have multiple interdependent scripts and have the browser > manage their ordering. > - Do all this without having to modify existing scripts. > >I must admit to not really understanding these requirements (script >execution can be made more or less free if they are designed to just >expose some functions, for example, and it's trivial to set up a script >dependency mechanism for scripts to run each other in order, and there's >no reason browsers can't parse scripts off the main thread, etc). But >since everyone else seems to think these are issues, let's ignore that. > >The proposals I've seen so far for extending the spec's script preloading >mechanisms fall into two categories: > > - provide some more control over the mechanisms already there, e.g. > firing events at various times, adding attributes to make the script > loading algorithm work differently, or adding methods to trigger > particular parts of the algorithm under author control. > > - provide a layer above the current algorithm that provides strong > semantics, but that doesn't have much impact on the loading algorithm > itself. > >I'm very hesitant to do the first of these, because the algorithm is _so_ >complicated that adding anything else to it is just going to result in >bugs in browsers. There comes a point where an algorithm just becomes so >hard to accurately test that it's a lost cause. > >The second seems more feasible, though. > >Would something like this, based on proposals from a variety of people in >the past, work for your needs? > >1. Add a "dependencies" attribute to <script> that can point to other > scripts to indicate that execution of this script should be delayed > until all other scripts that are (a) earlier in the tree order and (b) > identified by this attribute have executed. > > <script id="jquery" src="jquery.js" async></script> > <script id="shims" src="shims.js" async></script> > <script dependencies="shims jquery" src="myscript.js" async></script> > > This would download jquery.js, shims.js, and myscript.js ASAP, without > blocking anything else, and would then run jquery.js and shims.js >ASAP, > in any order, and then once both have executed, it would execute > myscript.js. > >2. Add an "whenneeded" boolean content attribute, a "markNeeded()" method, > and an internal "is-needed flag" (initially false) to the <script> > element. When a script is about to execute, if its whenneeded="" > attribute is set, but its "is-needed" flag is not, then delay > execution. Calling markNeeded() on a script that has a whenneeded > boolean but that has not executed yet first causes the markNeeded() > method on all the script's dependencies to be called, and then causes > this script to become ready to execute. > > <script id="jquery" src="jquery.js" async whenneeded></script> > <script id="shims" src="shims.js" async whenneeded></script> > <script id="myscript" dependencies="shims jquery" src="myscript.js" > async whenneeded></script> > > This would download jquery.js, shims.js, and myscript.js ASAP, and >then > wait for further instructions. > > document.getElementById('myscript').markNeeded(); > > This would then cause the scripts to execute, first jquery.js and > shims.js (in any order), and then myscript.js. If any hadn't finished > downloading yet, it would first wait for that to finish. > > (We could make markNeeded() return a promise, too.) > >Is there a need for delaying the download of a script as well? (If so, we >could change whenneeded="" to have values, like whenneeded="execute" vs >whenneeded="download" or something.) > >Is there something this doesn't handle which it would need to handle? > >-- >Ian Hickson U+1047E )\._.,--....,'``. fL >http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,. >Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Received on Wednesday, 10 July 2013 01:32:10 UTC