Home » Nodejs » Lazy loading in node.js

Lazy loading in node.js

Posted by: admin November 29, 2017 Leave a comment

Questions:

I was wondering if using require() in node.js was the equivalent to lazy loading?

For example if I had a function that required a specific node.js package that wasn’t needed anywhere else in my code am I best to use require() inside of that function to include the needed package only when that function is called.

I’m also unsure if this will provide any performance improvements given my lack of understanding around the node.js architecture? I presume it will use less memory per connection to my server. However will it increase I/O to the disk when it has to read the package, or will this be a one off to get it in memory?

If this is the case how far should I take this, should I be trying to write node.js packages for as much code as I can?

Answers:

require() is on-demand loading. Once a module has been loaded it won’t be reloaded if the require() call is run again. By putting it inside a function instead of your top level module code, you can delay its loading or potentially avoid it if you never actually invoke that function. However, require() is synchronous and loads the module from disk so best practice is to load any modules you need at application start before your application starts serving requests which then ensures that only asynchronous IO happens while your application is operational.

Node is single threaded so the memory footprint of loading a module is not per-connection, it’s per-process. Loading a module is a one-off to get it into memory.

Just stick with the convention here and require the modules you need at the top level scope of your app before you start processing requests. I think this is a case of, if you have to ask whether you need to write your code in an unusual way, you don’t need to write your code in an unusual way.

Questions:
Answers:

If you want to lazy load modules, its now possible with ES6 (Node v6)

Edit: This will not work if you need to access properties of require (like
require.cache).

module.js

console.log('Module was loaded')
exports.d=3

main.js

var _require = require;
var require = function (moduleName) {
    var module;
    return new Proxy(function () {
        if (!module) {
            module = _require(moduleName)
        }
        return module.apply(this, arguments)
    }, {
        get: function (target, name) {
            if (!module) {
                module = _require(moduleName)
            }
            return module[name];
        }
    })
};

console.log('Before require');
var a = require('./module')
console.log('After require');
console.log(a.d)
console.log('After log module');

output

Before require
After require
Module was loaded
3
After log module