Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: lazy loading and cleanup #20734

Closed
wants to merge 3 commits into from
Closed

Conversation

jasnell
Copy link
Member

@jasnell jasnell commented May 15, 2018

This is a start towards an very incremental refactoring of core module loading the occurs at startup. Every core module that is loaded automatically adds to the overall cold start time of the node.js process. While this specific PR is not likely to have much impact, the goal is to start moving towards lazy-loading where it is practical. Fixed a bug or two and cleaned up a few other bits along the way.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines

@nodejs-github-bot nodejs-github-bot added the lib / src Issues and PRs related to general changes in the lib or src directory. label May 15, 2018
@mscdex
Copy link
Contributor

mscdex commented May 15, 2018

We should definitely have some benchmark runs for the affected modules to make sure no runtime overhead is incurred with these changes.

@jasnell
Copy link
Member Author

jasnell commented May 15, 2018

Yep, I'll be running some in a bit. I was fairly selective to avoid hot paths but benchmarks would definitely be good.

lib/assert.js Outdated
return buffers;
function getBuffer(filename, assertLine) {
// Lazy load
const { openSync, closeSync, readSync } = require('fs');
Copy link
Contributor

@mscdex mscdex May 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we could do more traditional lazy loading and avoid the call to require() every time, by checking the undefined-ness of one of the variables.

Something like:

{
  let openSync;
  let closeSync;
  let readSync;
  var getBuffer = function getBuffer(filename, assertLine) {
    if (openSync === undefined)
      ({ openSync, closeSync, readSync } = require('fs'));

    // ...
  };
}

Or we could just move the variables to the top level since some of them are used in other places to avoid requiring the same function (e.g. openSync) multiple times for different fs functions (e.g. getBuffer and getErrMessage)?

lib/fs.js Outdated
@@ -86,7 +104,7 @@ Object.defineProperty(fs, 'promises', {
process.emitWarning('The fs.promises API is experimental',
'ExperimentalWarning');
}
return promises;
return require('internal/fs/promises');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to move the require in the if (warn) check to only require it once and to use a extra variable.

@@ -69,6 +66,11 @@ function createRepl(env, opts, cb) {
}

function setupHistory(repl, historyPath, ready) {
// Lazy load
const fs = require('fs');
const path = require('path');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path is definitely always loaded eager and I do not see how we can prevent that as it is necessary during bootstrapping. So this should probably not be lazy loaded.

@@ -47,15 +47,16 @@ const {
makeRequireFunction,
addBuiltinLibsToObject
} = require('internal/modules/cjs/helpers');
const internalUtil = require('internal/util');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I am not mistaken it will not (easily) be possible to lazy load internal/util. I tried to do that and it is used for a lot of things that are eagerly loaded.

@BridgeAR
Copy link
Member

I think it is great to do more lazy loading but this will only reduce two files loaded. One is dns (that conflicts with #20567) and the other one is internal/fs/promises.

However, this changes multiple requires to lazy load that are going to be loaded on bootstrap one way or the other. When working on #20567 I payed careful attention to only lazy load things that won't be lazy loaded otherwise. So I personally would like to have a approach where we always only add lazy loading where we make sure that a file is indeed not required for bootstrapping anymore. This should be easy as soon as #20567 landed by just lowering the number of files loaded in the corresponding test. That way we are able to verify the gain instead of just complicating code paths that won't have any benefit otherwise (even though there are a couple of other things in this PR that are worth doing).

@jasnell
Copy link
Member Author

jasnell commented May 15, 2018

I think it is great to do more lazy loading but this will only reduce two files loaded. One is dns (that conflicts with #20567) and the other one is internal/fs/promises.

As I said in the original post: "While this specific PR is not likely to have much impact, the goal is to start moving towards lazy-loading where it is practical. Fixed a bug or two and cleaned up a few other bits along the way."

The goal here is not to be comprehensive but to take a very incremental and slow approach to ensure things aren't broken as we go.

@jasnell
Copy link
Member Author

jasnell commented May 16, 2018

Thinking about this PR again... I'm going to split the commits up into smaller PRs. Too much happening in this one.

@jasnell
Copy link
Member Author

jasnell commented May 16, 2018

Moved various commits out to separate PRs. Remaining commits in this PR can be handled separately. Closing.

@jasnell jasnell closed this May 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lib / src Issues and PRs related to general changes in the lib or src directory.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants