-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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: improve lazy loading #14167
lib: improve lazy loading #14167
Conversation
The lazy assert should already be in place when calling any of the E functions.
I don't like it as is. It spreads the Object.defineProperty(this, 'lasyErrors', {
get() {
const value = require('errors');
Object.defineProperty(this, 'lasyErrors', {value});
return value;
}
); |
Does this expense actually add up to anything significant in a realistic scenario? |
@refack I guess you mean something like the following? const lazy = {};
Object.defineProperty(lazy, 'util', {
configurable: true,
get() {
const value = require('util');
Object.defineProperty(lazy, 'util', { value, enumerable: true });
return value;
}
});
const util = lazy.util; I know that spreading is not nice but if it's a function call or not is not much of a difference in that case. @Fishrock123 I'll run some benchmarks later on. I just checked the different lazy loading times them self and those are way faster. |
I agree that dynamically it's the same, the difference is in static analysis, if it's a function (or property) at the top it's easier to spot, visually or with tools. As for a property you can set it on the |
Actually const lazy = {
get util() {
const value = require('util');
Object.defineProperty(this, 'util', { value, enumerable: true });
return value;
},
...
} |
Overall I'm not a fan. I prefer to keep lazy loading only when absolutely necessary, mostly to avoid circular references caused by early loading. |
lib/internal/process.js
Outdated
} | ||
return _lazyConstants; | ||
} | ||
var lazyConstants; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re #14167 (comment) comment this could be inlined.
lib/internal/process/stdio.js
Outdated
errors = require('internal/errors'); | ||
return errors; | ||
} | ||
var lazyError; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inline
lib/internal/process/warning.js
Outdated
@@ -5,24 +5,12 @@ const prefix = `(${process.release.name}:${process.pid}) `; | |||
|
|||
exports.setup = setupProcessWarnings; | |||
|
|||
var errors; | |||
var fs; | |||
var lazyErrors; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
errors can be inlined
Simpler which is definitely better 👍 |
Do not lazy load if not necessary and prevent function calls.
e62d447
to
a2e95aa
Compare
@refack there's still the property lookup and it is still faster to just check if the variable is defined or not. This was the way how lazy loading was used in other spots as well and with the simple |
Ack |
lib/net.js
Outdated
var cluster; | ||
var dns; | ||
// Lazily loaded | ||
var cluster = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could probably be required up front as well but cluster
is likely not required in many places that use net
and therefore I kept it as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So could you document that:
// `cluster` is only used by `listenInCluster` so for startup performance
// reasons it's lazy loaded.
LGTM. Aside from this PR, I'm not too big of a fan of using |
@refack I added the comment. I also moved a statement to prevent lazy loading under some conditions. |
The link to the CI: https://ci.nodejs.org/job/node-test-commit/11256/ ✔️ |
* internal/errors - assert should already be in place when calling any of the message generating functions. * No lazy load if not necessary. * Replace function calls with `if`s. PR-URL: nodejs#14167 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Timothy Gu <[email protected]>
Landed in b55ab01 |
This doesn’t land cleanly on 8.x; if you can, please follow the guide and raise a backport PR, if you don’t think it make sense let me know and we’ll add the |
Ping @BridgeAR .. re: backport. |
* internal/errors - assert should already be in place when calling any of the message generating functions. * No lazy load if not necessary. * Replace function calls with `if`s. PR-URL: nodejs#14167 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Timothy Gu <[email protected]>
* internal/errors - assert should already be in place when calling any of the message generating functions. * No lazy load if not necessary. * Replace function calls with `if`s. PR-URL: #14167 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Timothy Gu <[email protected]>
Should this be backported to |
I do not see the necessity to backport this. So I changed the labels accordingly. |
The function call plus the existence check is more expensive than inlining the lazy require.
A few lazyAssert calls were obsolete as the assert would have to be required before.
I also moved a few lazy requires in the specific code path as it would not be required at all in some cases.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
lib