53

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?

2 Answers 2

73

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Peter, this made it all make a lot more sense.
Early loading doesn't make sense for CLI tools (except for testing, where you could disable it temporarily).
@PeterLyons can you explain to me the line "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". I understand what a single thread is , do you mean to say that whatever the number of connections to the server, a particular module will be loaded only once across the whole application?
17

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

4 Comments

It's subtle but that Proxy class there looks fancy! Nice find.
I removed the var part of reassignment of require since it's technically global. This works great except for using it on classes. I have some code that looks like new (require('./somefile.js')) - return module.apply(this, arguments) TypeError: Class constructor cannot be invoked without 'new' at new Proxy.get
I think this will not work if somebody does const { old_name: new_name, foo: f, bar: b } = require('module');. See stackoverflow.com/a/48952855/334451 for details.
Do import statements use require under the hood? And if so, would this also cause imported packages to be loaded lazily?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.