Search code examples
javascriptrequirejsamd

How to use browser parallel loading but still maintain the order of scripts using RequireJS


I have this friend, who hates RequireJS, I recently started using it & I like it, but by his arguments, I started feeling like I might end up like him and give up using RequireJS.

require(['one'],function(){
    require(['two'],function(){
        require(['three'],function(){

        });
    });
});

Above code is fairly straight-forward, three depends on two & two depends on one. That makes the browser to load one first & then two & then three in sequence, that's how requirejs handles it, which makes the site real slow if there are lots of these kinds of dependencies.

Browser parallel loading feature it not used at all.

I want to know if there is any way in which require loads all these files asyncronously but makes sure to maintain the order in their execution, so that browser parallelism can be used.


Solution

  • RequireJS is a powerful tool that allows us to load script asynchronously (means we start the loading of each one, and don't wait until it is actually loaded), but still manage dependencies (if one file depends on another, we wanna wake sure the dependency will be loaded beforehand). The way you use RequireJS is not what it is made for. The callback function inside the require is called as soon as the dependency module is loaded ('one', 'two', 'three'). So you are just loading all the modules sequentially, not asynchronously (one is loaded -> callback function is called -> two is loaded -> callback function is called -> three is loaded -> callback function is called). That makes no sense. The way it is supposed to be:

    in your HTML file:

    <script data-main='main.js' src='require.js'></script>
    

    in your main.js file (some file you wrote inside your script tag as data-main):

    require(['one'], function(one){
        one.function1();
    });
    

    in one.js:

    define(['two', 'three'], function(two, three) {
        return {
            function1 : function() {
                two.function2();
                three.function3();
                console.log('one');
            }
        }
    });
    

    in two.js:

    define([], function() {
        return {
            function2 : function() {
                console.log('two');
            }
        }
    });
    

    in three.js:

    define([], function() {
        return {
            function3 : function() {
                console.log('three');
            }
        }
    });
    

    In my example 'one' depends on 'two' and 'three' (it requires function2() from 'two' and function3() from 'three'), 'two' and 'three' have no dependencies. This example code assumes all the files are in one folder (including require.js). As a result, we see 'two', 'three', 'one' printed (in that order).