Re: [whatwg] Script preloading

This is a good proposal and I'm hugely excited to see this getting more
attention! Thanks so much for bringing it up again.

There's one state that's not represented here which is "download but do not
run", an "inactive" flag, if you will. I know this is important is some
situations where the overhead to compile code is potentially large...but
it's an edge-case. markNeeded() might cover it.

Regarding dependencies="..."; have you considered a way to set up script
groups instead of ID-based dependencies? E.g.:

  <script group="core" src="jquery.js" async whenneeded></script>
  <script group="shims" src="shims.js" async whenneeded></script>
  <script id="myscript" group="core shims" src="myscript.js"
             async whenneeded></script>

With the idea being that each item depends on other items in the specified
group in document order. I'm not sure it's better, but it might enable less
a-priori collaboration across large sets of dependent scripts.

Also, have you talked at all with Yehuda, Dave, and Sam about how this
might interact with ES6 Module Loaders? It might be worth a discussion just
to see if there are any bits of common infrastructure that both designs can
identify/re-use. They'll all bottom out at fetch() someplace, but
understanding how they interact might be helpful. E.g., could I specify a
named module loader for a <script>? That'd make transpilers infinitely more
useful.

Again, thanks for posting this. I'm incredibly excited about this design
and would support it without changes.



On Tue, Jul 9, 2013 at 8: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.html
>
> 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 17:07:56 UTC