Search code examples
javascriptbackbone.jsrequirejsmarionette

How to structure a backbone/marionette application without loading everything upfront


I have a backbone.js with marionette app that uses require.js. I also use handlebars with the hbs plugin found here https://github.com/SlexAxton/require-handlebars-plugin.

At the start of my application I load up a router and a controller which of course requires the views so it can instantiate them and show them on the region.

So at start the controller asks for the view, the view requires it's js script dependencies and hbs preloads the templates. This results in my application starting with all javascript files and html templates loaded upfront, like the user is downloading a desktop application. I can confirm this by looking at the developer tools tab to see what is downloaded.

var A=require("a") is loaded even if it is in a conditional bracket.

Is there any way to load up the js (which themselves load the templates (html files)) only when the user actually navigates to the controller's function?


Solution

  • From the docs:

    The AMD loader will parse out the require('') calls by using Function.prototype.toString()

    Which means, if you do this:

    define(function (require) {
        if(x) {
            var y = require('y');
        }
    });
    

    RequireJS will resolve all require calls before the function gets called, wrapping require in a conditional achieves nothing.

    Keep in mind that doing a single request for a missing script takes way longer than parsing a lot of code that is never called. What you are trying to do is probably not worth it and could even have negative effects. For production usage, it is recommended to use the optimizer, which bundles everything in a single file anyway.

    To answer your question, avoid the CommonJS style and call the async require inside modules:

    define([], function () {
        if(x) {
            require(['y'], function (y) {
                y.doStuff();
            });
        }
    });