[whatwg] Script preloading
ian at hixie.ch
Tue Jul 9 12:39:45 PDT 2013
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:
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
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
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"
This would download jquery.js, shims.js, and myscript.js ASAP, and then
wait for further instructions.
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. `._.-(,_..'--(,_..'`-.;.'
More information about the whatwg