What's the difference between Require.js and simply creating a <script> element in the DOM?

maxedison picture maxedison · Feb 6, 2011 · Viewed 32.7k times · Source

What's the difference between using Require.JS amd simply creating a <script> element in the DOM?

My understanding of Require.JS is that it offers the ability to load dependencies, but can this not simply be done by creating a <script> element that loads the necessary external JS file?

For example, lets assume I have the function doStuff(), which requires the function needMe(). doStuff() is in the external file do_stuff.js, while needMe() is in the external file need_me.js.

Doing this the Require.JS way:

define(['need_me'],function(){
    function doStuff(){
        //do some stuff
        needMe();
        //do some more stuff
    }
});

Doing this by simply creating a script element:

function doStuff(){
    var scriptElement  = document.createElement('script');
    scriptElement.src = 'need_me.js';
    scriptElement.type = 'text/javascript';
    document.getElementsByTagName('head')[0].appendChild(scriptElement);

    //do some stuff
    needMe();
    //do some more stuff
}

Both of these work. However, the second version doesn't require me to load all of the Require.js library. I don't really see any functional difference...

Answer

jmort253 picture jmort253 · Jul 1, 2013

What advantages does Require.JS offer in comparison to simply creating a element in the DOM?

In your example, you're creating the script tag asynchronously, which means your needMe() function would be invoked before the need_me.js file finishes loading. This results in uncaught exceptions where your function is not defined.

Instead, to make what you're suggesting actually work, you'd need to do something like this:

function doStuff(){
    var scriptElement  = document.createElement('script');
    scriptElement.src = 'need_me.js';
    scriptElement.type = 'text/javascript';

    scriptElement.addEventListener("load", 
        function() { 
            console.log("script loaded - now it's safe to use it!");

            // do some stuff
            needMe();
            //do some more stuff

        }, false);

    document.getElementsByTagName('head')[0].appendChild(scriptElement);

}

Arguably, it may or may not be best to use a package manager such as RequireJS or to utilize a pure-JavaScript strategy as demonstrated above. While your Web application may load faster, invoking functionality and features on the site would be slower since it would involve waiting for resources to load before that action could be performed.

If a Web application is built as a single-page app, then consider that people won't actually be reloading the page very often. In these cases, preloading everything would help make the experience seem faster when actually using the app. In these cases, you're right, one can merely load all resources simply by including the script tags in the head or body of the page.

However, if building a website or a Web application that follows the more traditional model where one transitions from page to page, causing resources to be reloaded, a lazy-loading approach may help speed up these transitions.