ES6 module loader issues: preloading, and CSS imports

Ian Hickson ian at
Tue Aug 19 09:52:29 PDT 2014

(For some reason, e-mails containing the following text have failed to 
make it to the es-discuss list. Not sure what's going on with that. 
Anyway, this is a new e-mail that contains more or less the same contents 
but changed a bit in case there's some filter or bug that the last e-mails 
were hitting.)

It would be helpful if there was a way that the module _execution_ (after 
it's been parsed and dependencies have been extracted) could be delayed by 
the loader.

Suppose a page is loading and has reached a quiescent state, and so the 
browser thinks "ok, time to preload some scripts". It might start with one 
script, and then find that it imports another, and would then fetch that 
one. But it doesn't want to actually execute anything, because the scripts 
haven't been invoked yet.

Since ES6 does all the heavy lifting of finding the imports in the source 
code and setting up all the linking, it would be good if the browser could 
rely on that but just put a stop to the final execution step until such 
time as the resource is actually needed. Doing this in the fetch or 
translate hooks wouldn't work because we need the instantiate hook to do 
its dependency tracking bit first.

It's possible, based on this and earlier e-mails about how to change 
dependencies, that really what we need is a new hook that splits 
"instantiate" in half -- half for handling dependencies, and half for 
handling execution. That might also enable the "instantiate" hook to 
change to not return a weird object or undefined. It would similarly 
address the "how do I add out-of-band dependencies" issue I mentioned 
earlier. Combined with changing where dependencies are first initialised, 
this would address most of the dependency issues I've raised, I think.

This would also allow for ES6 import syntax to be used inline to declare 
some dependencies, as in the case of an inline script marked as being 
on-demand containing something like:

     import "jquery";
     import "jquery/animations";
     import "myapp/logic";

If the browser could notice that this was an inline script and have the 
ES6 module system pre-parse it to discover the imports, it could preload 
them and then when the script element's execute() or load() method 
(whatever we end up calling it) is invoked it could just unblock the 
execution and immediately have the scripts run.

Assuming we use the ES6 module loader to handle all the loads in an HTML 
document, in the Web context, there are also some interesting questions to 
resolve around the issue of de-duping.

Suppose you had an inline style element markup containing:

    @import "";

...followed by an external script element src="" pointing to:

This causes foo.x to be evaluated once as a style sheet, and once as a 
script. In the new world, though, if every load goes through the ES6 
module system, how do we distinguish them in the module registry?

Similarly, consider the reverse case of an inline script module saying:

    import "";

...followed by an inline style block saying:

    @import "";

After the module's import, foo.x is in the registry as an ES6 module. But 
the semantics of the @import rule are that it must be interpreted as CSS, 
so that doesn't work.

It would be great if it was possible to attach metadata to the key that is 
used in the registry that would be part of the registry key but not 
exposed in the module API. For example, @import could tag all its modules 
as "CSS", so that the above would be keyed as {"", 
CSS}. Regular imports wouldn't key anything, so that in the case of an 
inline CSS block followed by an inline ES6 module both importing the same 
file, the second import would find the pre-existing CSS import rather than 
try to introduce a new one.

Ian Hickson               U+1047E                )\._.,--....,'``.    fL       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

More information about the es-discuss mailing list