This is a plain installation of the strongloop module in a fresh docker container with node-v0.10.39 (see Dockerfile or docker pull
strongloop/strongbox:dev). The only difference between the 2 containers is the npm@3 container had npm install -g npm@3
run on it before these tests.
strongbox@23e5cea0a3f1:~$ npm --version
2.11.3
strongbox@23e5cea0a3f1:~$ time npm install -g strongloop && du -sch /usr/local/lib/node_modules/strongloop
real 2m45.194s
user 2m12.300s
sys 2m49.010s
424M /usr/local/lib/node_modules/strongloop
424M total
strongbox@bf836c8f0be9:~$ npm --version
3.0.0
strongbox@bf836c8f0be9:~$ time npm install -g strongloop && du -sch /usr/local/lib/node_modules/strongloop
real 10m7.332s
user 4m42.900s
sys 1m43.220s
315M /usr/local/lib/node_modules/strongloop
315M total
Now we nuke the installations and try again, this time opting out of the dedupe hinting provided by the optionalDependencies
by adding the --no-optional
flag. In other words, we're telling npm to install less dependencies by ignoring some of them.
strongbox@23e5cea0a3f1:~$ npm --version
2.11.3
strongbox@23e5cea0a3f1:~$ time npm install -g --no-optional strongloop && du -sch /usr/local/lib/node_modules/strongloop
real 2m58.066s
user 2m26.510s
sys 3m19.090s
514M /usr/local/lib/node_modules/strongloop
514M total
strongbox@bf836c8f0be9:~$ npm --version
3.0.0
strongbox@bf836c8f0be9:~$ time npm install -g --no-optional strongloop && du -sch /usr/local/lib/node_modules/strongloop
real 8m26.624s
user 6m15.320s
sys 1m44.860s
382M /usr/local/lib/node_modules/strongloop
382M total
This isn't really debatable, and we're not talking about a few percent slower, we're talking about talking 4x longer on average. I know it's doing of cool stuff behind the scenes, but I'm not sure it's 4x as cool. I would bet money that there are already plans to improve the speed.
Even without the deduplication hinting of the optionalDependencies
, npm@3 still made a smaller installation than npm@2 did with the hinting. Obviously there's a trade-off here, since I didn't want to spend hours running and re-running pkgcount to see which duplicate dependencies were worth hoisting.
There are more than a few modules out there that are written with some (incorrect) assumptions that were previously only triggered by corner cases but will now be triggered frequently. At the top of that list is any module that implemented a singleton with the assumption that each module would get its own instance of the singleton (npm/npm#8743). In other words, module-cache-hosted singletons will now be even more singleton.
There are some modules that were written with the incorrect assumption that there would only be one version of the module in the dependency tree and they relied on this to provide a singleton interface. This is basically the opposite of the previous problem, so naturally these modules will benefit from the change - though they will still have problems with npm link
.