whatwg / loader

Loader Standard
https://whatwg.github.io/loader/
Creative Commons Zero v1.0 Universal
607 stars 45 forks source link

Async loading of bundles #59

Closed tinganho closed 9 years ago

tinganho commented 9 years ago

Hi, I want to propose async loading of bundles. I don't know if the spec already cover this or if you already have discussed this. Though cannot find similar discussion anywhere. Just some heads up, I'm having some difficulty understanding the current spec. So I use my own code example below.

Problem

Because of load time sometimes it is not suitable to bundle everything into one file. One solution is to bundle your application into multiple bundles instead. Another solution is to use http2 with server push. But you can still use server push and bundle at the same time(since you already need to uglify your application code, adding another build step for the bundling won't be that big). Also bundling saves the client from decoding a lot of http2 headers. But also cache-aware server push might need SW support to know which files to be pushed(Here is one discussion in https://github.com/h2o/h2o/issues/421#issuecomment-126988105), so setting up server push correctly isn't the most trivial task.

Proposal

One solution to above problems is to let the loader being able to load bundles. Since bundles need at least one root file(not necessarily) to traverse all files and bundle them — we can add a map to the loader, that maps root files to bundle files.

In example code(sorry, don't know the whole loader spec and have some difficult to understand it):

Loader.bundles({
    '/page1.js': 'page1.bundle.js', 
    '/page2.js': 'page2.bundle.js', 
})

All root files defines(not necessarily) an API interface to interact with so we can use the same code for dev and production environment.

if (url === '/page1') {
    var page1  = await Loader.import('/page1.js'); // loads bundle page1.bundle.js instead of page1.js on production
    page1.init();
}
guybedford commented 9 years ago

It is certainly possible to implement something like this via the loader hooks. SystemJS has exactly this kind of an implementation in https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#bundle.

tinganho commented 9 years ago

@guybedford great totally missed that systemjs supported this.

matthewp commented 9 years ago

Bundling is not part of this specification. I do believe that a common bundling format needs to emerge to accommodate the needs of ES2015 modules (and Guy's System.register could very well be that format but it needs to be discussed as an independent proposal outside of Systemjs).

Sadly http2 and ES2015 module format does not solve the need for bundling even in a development environment. But the loader spec might not be the place for that discussion.

caridy commented 9 years ago

Bundling and folding mechanism will emerge for sure, but not in this repo.

matthewp commented 9 years ago

@caridy I've noticed you use the term "folding" a bit but I'm not familiar with what you mean by that, can you explain?

caridy commented 9 years ago

@matthewp

main.js

import foo from "foo"';
export default function () {
    foo();
    return 'ready...';
}

foo.js

export default function () {
    console.log('do something...');
}

If you application only relies on main.js (importing it and calling its default export), it doesn't really matter if main.js uses foo.js or not, all that can be abstracted, we can have tools that will produce a new es6 module called main.js with the following content:

function foo__default__() {
    console.log('do something...');
}

export default function () {
    foo__default__();
    return 'ready...';
}

and everything will continue to work as expected, because the public interface of main.js (its default and named exports) remains the same, but its dependencies were folded into its own source code. I haven't get a chance to work on any tool to achieve this, but I will, or will be happy to help others :)

advantages of this over bundling:

these are, from the top of my head, some of the stuff related to what I call folding of modules.

guybedford commented 9 years ago

Nice, I also really like the name fold here.

caridy commented 9 years ago

image

electricessence commented 8 years ago

Super Lazy :)