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

Performance issue in macro-config's babelPluginConfig #1399

Open
raycohen opened this issue Apr 19, 2023 · 1 comment
Open

Performance issue in macro-config's babelPluginConfig #1399

raycohen opened this issue Apr 19, 2023 · 1 comment

Comments

@raycohen
Copy link
Contributor

I've got a monorepo using a yarn workspace with about 100 addons, on a classic (non-embroider) build. Booting takes a long time and I'm investigating performance improvements. I came across almost 3 seconds spent inside babelPluginConfig. About 1.5s is spent in crypto/hash#update, and then readFileSync and statSync (via findUp) are around 400ms each.

From what I can tell, it is repeatedly finding and reading the same yarn.lock file, and creating a hash with the same yarn.lock file contents and project dependency list.

I'm wondering if we can avoid some of this repetition. If so I can contribute a PR. It seems like at least the findUp result per appRoot value could be reused. I don't think the contents of yarn.lock or gatherAddonCacheKey(appOrAddonInstance.project) are changing during the time I'm looking at but it seems like this code is intended to catch changes to those?

let lockFilePath = findUp.sync(['yarn.lock', 'package-lock.json', 'pnpm-lock.yaml'], { cwd: self.appRoot });
if (!lockFilePath) {
lockFilePath = findUp.sync('package.json', { cwd: opts.appPackageRoot });
}
let lockFileBuffer = lockFilePath ? fs.readFileSync(lockFilePath) : 'no-cache-key';
// @embroider/macros provides a macro called dependencySatisfies which checks if a given
// package name satisfies a given semver version range. Due to the way babel caches this can
// cause a problem where the macro plugin does not run (because it has been cached) but the version
// of the dependency being checked for changes (due to installing a different version). This will lead to
// the old evaluated state being used which might be invalid. This cache busting plugin keeps track of a
// hash representing the lock file of the app and if it ever changes forces babel to rerun its plugins.
// more information in issue #906
let hash = crypto.createHash('sha256');
hash = hash.update(lockFileBuffer);
if (appOrAddonInstance) {
// ensure that the actual running addon names and versions are accounted
// for in the cache key; this ensures that we still invalidate the cache
// when linking another project (e.g. ember-source) which would normally
// not cause the lockfile to change;
hash = hash.update(gatherAddonCacheKey(appOrAddonInstance.project));
}
let cacheKey = hash.digest('hex');

Screenshot 2023-04-19 at 1 54 01 PM

@NullVoxPopuli
Copy link
Collaborator

I think your assumption is correct -- yeah, if you have time for a PR, that'd be super appreciated <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants