Skip to content

Instantly share code, notes, and snippets.

@isaacs
Created February 5, 2020 17:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isaacs/9029876bcfd7f8591fc31604cb055199 to your computer and use it in GitHub Desktop.
Save isaacs/9029876bcfd7f8591fc31604cb055199 to your computer and use it in GitHub Desktop.
Preliminary timing of npm v6 vs Arborist (ie, npm v7) in a few scenarios.
$ npm i
npm WARN deprecated core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
npm WARN deprecated @types/vfile-message@2.0.0: This is a stub types definition. vfile-message provides its own type definitions, so you do not need this installed.
npm WARN deprecated core-js@1.2.7: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
> fsevents@1.2.11 install /Users/isaacs/dev/blog.izs.me/node_modules/fsevents
> node-gyp rebuild
SOLINK_MODULE(target) Release/.node
CXX(target) Release/obj.target/fse/fsevents.o
SOLINK_MODULE(target) Release/fse.node
> sharp@0.23.4 install /Users/isaacs/dev/blog.izs.me/node_modules/sharp
> (node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)
info sharp Using cached /Users/isaacs/.npm/_libvips/libvips-8.8.1-darwin-x64.tar.gz
> core-js@2.6.11 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"
Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!
The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
> https://opencollective.com/core-js
> https://www.patreon.com/zloirock
Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)
> core-js-pure@3.6.4 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/core-js-pure
> node -e "try{require('./postinstall')}catch(e){}"
> gatsby-telemetry@1.1.49 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/gatsby-telemetry
> node src/postinstall.js || true
> cwebp-bin@5.1.0 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/cwebp-bin
> node lib/install.js
✔ cwebp pre-build test passed successfully
> mozjpeg@6.0.1 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/mozjpeg
> node lib/install.js
✔ mozjpeg pre-build test passed successfully
> pngquant-bin@5.0.2 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/pngquant-bin
> node lib/install.js
✔ pngquant pre-build test passed successfully
> gatsby-cli@2.8.29 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/gatsby/node_modules/gatsby-cli
> node scripts/postinstall.js
> gatsby@2.19.12 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/gatsby
> node scripts/postinstall.js
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN notsup Unsupported engine for gatsby-redirect-from@0.1.1: wanted: {"node":"^10.0.0"} (current: {"node":"13.7.0","npm":"6.13.7"})
npm WARN notsup Not compatible with your version of node/npm: gatsby-redirect-from@0.1.1
npm WARN tsutils@3.17.1 requires a peer of typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta but none is installed. You must install peer dependencies yourself.
added 2158 packages from 1042 contributors and audited 23678 packages in 44.039s
$ npm i
> fsevents@1.2.9 install /Users/isaacs/dev/blog.izs.me/node_modules/fsevents
> node install
node-pre-gyp WARN Using request for node-pre-gyp https download
node-pre-gyp WARN Tried to download(404): https://fsevents-binaries.s3-us-west-2.amazonaws.com/v1.2.9/fse-v1.2.9-node-v79-darwin-x64.tar.gz
node-pre-gyp WARN Pre-built binaries not found for fsevents@1.2.9 and node@13.7.0 (node-v79 ABI, unknown) (falling back to source compile with node-gyp)
SOLINK_MODULE(target) Release/.node
CXX(target) Release/obj.target/fse/fsevents.o
SOLINK_MODULE(target) Release/fse.node
COPY /Users/isaacs/dev/blog.izs.me/node_modules/fsevents/lib/binding/Release/node-v79-darwin-x64/fse.node
TOUCH Release/obj.target/action_after_build.stamp
> sharp@0.23.4 install /Users/isaacs/dev/blog.izs.me/node_modules/sharp
> (node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)
info sharp Using cached /Users/isaacs/.npm/_libvips/libvips-8.8.1-darwin-x64.tar.gz
> core-js@2.6.10 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/core-js
> node postinstall || echo "ignore"
Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!
The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
> https://opencollective.com/core-js
> https://www.patreon.com/zloirock
Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)
> core-js-pure@3.4.7 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/core-js-pure
> node -e "try{require('./postinstall')}catch(e){}"
> gatsby-telemetry@1.1.42 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/gatsby-telemetry
> node src/postinstall.js || true
> cwebp-bin@5.1.0 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/cwebp-bin
> node lib/install.js
✔ cwebp pre-build test passed successfully
> mozjpeg@6.0.1 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/mozjpeg
> node lib/install.js
✔ mozjpeg pre-build test passed successfully
> pngquant-bin@5.0.2 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/pngquant-bin
> node lib/install.js
✔ pngquant pre-build test passed successfully
> gatsby-cli@2.8.16 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/gatsby-cli
> node scripts/postinstall.js
> gatsby@2.18.7 postinstall /Users/isaacs/dev/blog.izs.me/node_modules/gatsby
> node scripts/postinstall.js
added 2282 packages from 1009 contributors and audited 23192 packages in 42.672s
$ node ../npm/arborist/scripts/reify.js . --quiet
{ path: '.', cache: '/Users/isaacs/.npm/_cacache', quiet: true }
warn Error: Unsupported engine
at checkEngine (/Users/isaacs/dev/npm/arborist/node_modules/npm-install-checks/index.js:15:25)
at c (/Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:318:21)
at Arborist.[checkEngine] (/Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:324:9)
at /Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:307:37 {
pkgid: 'gatsby-redirect-from@0.1.1',
current: { node: 'v13.7.0', npm: undefined },
required: { node: '^10.0.0' },
code: 'EBADENGINE'
}
resolved 2248 deps in 55.0339231371s
$ node ../npm/arborist/scripts/reify.js . --quiet
{ path: '.', cache: '/Users/isaacs/.npm/_cacache', quiet: true }
warn Error: Unsupported engine
at checkEngine (/Users/isaacs/dev/npm/arborist/node_modules/npm-install-checks/index.js:15:25)
at c (/Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:318:21)
at Arborist.[checkEngine] (/Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:324:9)
at /Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:307:37 {
pkgid: 'gatsby-redirect-from@0.1.1',
current: { node: 'v13.7.0', npm: undefined },
required: { node: '^10.0.0' },
code: 'EBADENGINE'
}
resolved 2282 deps in 32.0592178756s
$ node ../npm/arborist/scripts/reify.js . --quiet
{ path: '.', cache: '/Users/isaacs/.npm/_cacache', quiet: true }
warn Error: Unsupported engine
at checkEngine (/Users/isaacs/dev/npm/arborist/node_modules/npm-install-checks/index.js:15:25)
at c (/Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:318:21)
at Arborist.[checkEngine] (/Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:324:9)
at /Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:307:37 {
pkgid: 'gatsby-redirect-from@0.1.1',
current: { node: 'v13.7.0', npm: undefined },
required: { node: '^10.0.0' },
code: 'EBADENGINE'
}
resolved 2282 deps in 25.0596706217s
$ node ../npm/arborist/scripts/reify.js . --quiet
{ path: '.', cache: '/Users/isaacs/.npm/_cacache', quiet: true }
warn Error: Unsupported engine
at checkEngine (/Users/isaacs/dev/npm/arborist/node_modules/npm-install-checks/index.js:15:25)
at c (/Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:318:21)
at Arborist.[checkEngine] (/Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:324:9)
at /Users/isaacs/dev/npm/arborist/lib/arborist/reify.js:307:37 {
pkgid: 'gatsby-redirect-from@0.1.1',
current: { node: 'v13.7.0', npm: undefined },
required: { node: '^10.0.0' },
code: 'EBADENGINE'
}
resolved 2248 deps in 9.0684172498s
@isaacs
Copy link
Author

isaacs commented Feb 5, 2020

Test project is https://github.com/isaacs/blog.izs.me, which as you can see, has north of 2200 deps in its tree.

Takeaways:

  • Arborist.buildIdealTree is way too slow. Need to dig into that and figure out where the bottleneck is. There's no reason why it should be taking 50% longer than npm v6. (It might not be able to get much faster, especially since there are a bunch of peer deps being appropriately placed here, and it's working a bit harder to dedupe, but it should be able to get closer, at least.)
  • A converted v1->v2 lockfile is significantly slower than using a v2 lockfile that was created fresh. That's really odd, since it should be effectively the same exact thing, but apparently not? It has fewer deps being added, but not that many fewer, and a difference of 40 extracts wouldn't have nearly much of an impact. Maybe the tree shape that was defined in the v1 lockfile is just slower to reify for some reason? (But like... a third of the time? That's strange.)
  • OMFG, cutting install time from 40s to 9s???? AYFKM? As far as I can tell, this is legit, even if it's only in one of the tested scenarios. Now the trick will be to get that kind of speed-up in the other scenarios. Turns out this is not legit. Lifecycle scripts are a thing, they weren't being run do to an out of date corgi doc setup on the registry which will be corrected soon.

@isaacs
Copy link
Author

isaacs commented Feb 5, 2020

LOL ok. Figured out why it's 9s instead of 25. I'm not a wizard.

turns out.

It's 9s because it's not running build scripts, because it's apparently trusting that the pacote.manifest will have accurately put the hasInstallScript into the package-lock, and thus it doesn't need to re-check.

with the converted package-lock.json:

ALL UNPACKED [ 7, 211135203 ]
MOVED BACK RETIRED UNCHANGED [ 7, 218827167 ]
RUN PRE 0 [ 0, 77834837 ]
RUN INST 1 [ 0, 78207470 ]
RUN POST 8 [ 19, 372691096 ]
DONE [ 20, 371173398 ]
DID LIFECYCLES [ 27, 596555562 ]

with the fresh v2 lockfile:

ALL UNPACKED [ 8, 455047755 ]
MOVED BACK RETIRED UNCHANGED [ 8, 462610683 ]
RUN PRE 0 [ 0, 6482707 ]
RUN INST 0 [ 0, 6848577 ]
RUN POST 0 [ 0, 6985906 ]
DONE [ 0, 7099275 ]
DID LIFECYCLES [ 8, 477644816 ]

So, the issue is that i'm properly converting from a v1 to v2 lockfile, but that our corgis are not up to date on the actual registry. We'll get that fixed, and the v2 lockfile will be ~25s, just like the converted one. Still a big improvement :)

@isaacs
Copy link
Author

isaacs commented Feb 5, 2020

Installing with npm v6 with --ignore-scripts, just to have an apples-to-apples comparison vs that 9s install time:

$ npm i --ignore-scripts
added 2158 packages from 1042 contributors and audited 23678 packages in 24.464s

Dropping from 24.5s to 9s is still pretty damn impressive, even if it's not as impressive as going from 40s to 9s 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment