W3C home > Mailing lists > Public > whatwg@whatwg.org > July 2013

[whatwg] Script preloading

From: Ian Hickson <ian@hixie.ch>
Date: Tue, 9 Jul 2013 19:39:45 +0000 (UTC)
To: whatwg@whatwg.org, getify@gmail.com, jaffathecake@gmail.com, travis.leithead@microsoft.com
Message-ID: <Pine.LNX.4.64.1307091607110.24681@ps20323.dreamhostps.com>

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 Tuesday, 9 July 2013 19:40:10 UTC

This archive was generated by hypermail 2.4.0 : Wednesday, 22 January 2020 17:00:03 UTC