NPM 3 slowness. Alternative cache implementation.

NPM 3 works significantly slower than its preceding version. Bad news is that development team is not going to do anything about it.
https://github.com/npm/npm/issues/8826
I've implemented an alternative cache based on junction point that works much faster. Instead of restoring each package it mirrors the whole node_modules folder from cache using junctions. This approach gave me a noticeable performance improvement. Restoring from cache happens almost instantaneously.

# This is a custom implementation of npm cache.
# It is significantly faster then original implementation and restores packages almost instantaneously.
$ErrorActionPreference = "Stop"
if (-not (Test-Path ".\node_modules")) {
Write-Host "node_modules folder is missing. Creating cache entry and junction point correspondingly."
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
# Calculating hash from package.json. We are using it as a key in our cache.
# todo: Currently we assume that there will be no collisions in MD5 cache. Ideally we should store package.json in cache and perform full comparison between files.
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes("package.json")))
Write-Host "Md5 from package.json: $($hash)"
# Cache is stored globally in %APPDATA% folder.
$npmCacheFolder = "$($env:APPDATA)\npm-quick-cache\$($hash)\node_modules"
New-Item -ItemType Directory -Force -Path $npmCacheFolder
# Creating junction point.
cmd /c mklink /j "node_modules" $npmCacheFolder
if (-not $?) {
throw "Failed to create junction point.";
}
}
$npmInstalledMarker = ".\.npm_installed";
# Performance optimization. it takes 9 seconds for npm to verify dependencies. We are creating folder that indicates that installation was performed already.
if (-not (Test-Path -LiteralPath $npmInstalledMarker)) {
# Install npm@3.3.4 if required (npm@3.3.4 the most stable version in the moment)
$npm = Test-Path -LiteralPath ".\node_modules\.bin\npm"
npm install npm@3.3.4
if (-not $?) {
throw "Npm Install failed";
}
# Install node packages
.\node_modules\.bin\npm install
if (-not $?) {
throw "Npm install failed";
}
New-Item -ItemType Directory -Force -Path $npmInstalledMarker
}
view raw npmcache.ps1 hosted with ❤ by GitHub

Comments

Popular posts from this blog

TFS Proxy not working: The source control proxy is not responding

Demystifying fast up-to-date check in Visual Studio C# projects