Yarn vs. npm: Installation Time
Yarn is a client for the npm registry, Node.js ecosystem for the packages. This new client will address performance, reliability, and security-related issues. Before diving into this article, which is about speed comparison, please read the introductory articles: npm's blog post on Yarn and the official announcement.
The timing of the Yarn release was spot on, as in the current project that I am working on, the package installation time has been an issue. I was curious about whether there was a simple solution. I tested real projects, and I'll share the results in this blog post. Enjoy!
Why does the time required to fetch dependencies matter?
Cloning the source code and running npm install
to fetch project dependencies is done once per machine. Why does it matter, then, how long this step takes? There are several reasons.
Most of the problems regarding package installation I have encountered are related to cloud deployment, which takes a lot of time.
Depending on the cloud deployment setup, the continuous integration service fetches dependencies, runs tests, and signals to other services that your source code has passed all tests. Then your cloud hosting provider starts to install those packages.
In one of the example projects, the client side is quite lightweight, and there is plenty more source code on the backend (written in C#).
You might think that fetching backend dependencies (with NuGet) and building C# code would be the heaviest step in the deployment, but that is not the case. The step in which JavaScript dependencies are fetched is the most time-consuming.
In my experience, the caching works well only in the local environment. This makes sense because the same machine is being used all the time, but things tend to be more dynamic in the cloud environment.
There have been many situations in which the client has asked to see changes in the test environment, and, even if the change has been ready code-wise, it has taken twenty minutes to actually see the change.
If we could cut down the time a bit without big changes or hurdles, then I would call switching to Yarn a success.
Test material
I tested the fresh package installation times with two production applications, and also with my blog. Here is some basic information about the projects:
Project 1
A medium-sized project with a backend written in C# and a frontend built using TypeScript, React, Redux, other bells and whistles.
Project 2
A medium-sized project in which SPA (single-page application) initial page load is served using Express.js. Executing npm install will install both frontend and backend dependencies. APIs are used for the business logic.
My blog
This very blog and website that you're now reading was created with the Ghost blogging platform + the Express application. You can find the source code here.
How I tested
Yarn version 0.16.1 and npm version 4.0.1 were used for testing. At the time I wrote this blog post, these were the latest versions.
Before running the install commands, I ran npm cache clean
, yarn cache clean
and rm ./node_modules/
.
I did the time tracking with a PowerShell command:
Measure-Command { .\measure.cmd }
Depending on a test, measure.cmd contained npm install
or yarn install
.
I ran each test three times (then took the average of each group of three) on my laptop using a 4G connection. After each test, I cleared the cache.
Results and Conclusion
Project | npm | Yarn | Difference |
---|---|---|---|
Project 1 | 3 mins 1 sec | 2 mins 43 secs | 9.94% faster |
Project 2 | 3 mins 49 secs | 2 mins 29 secs | 34.93% faster |
This site | 4 mins 6 secs | 3 mins 21 secs | 18.29% faster |
Looks promising indeed! Unfortunately, the project that resulted smallest decrease in the dependency installation time (10%) was the one where a greater change was most desired.
While playing with Yarn, I found the output formatting a bit more informative than regular npm, and there weren't any issues with installing packages.
One thing to note: When you publish a new package, it will be in the npm repository, but Yarn will use its own repository when you fetch packages. I haven't investigated what kind of black magic is going on with the registry that Yarn uses for fetching data.
Give Yarn a go and let me know the results.