The response from the nest
cli command from NestJS (npm i -g @nestjs/cli
) in a Docker Development container with Visual Studio Code on Windows 10 is suddenly very slow. At first it works fine but at some point, for instance after deleting a directory in the src
folder, the nest
command gets very slow.
Example:
node ➜ /workspaces/Servers/terminal-server (master ✗) $ time nest --help
[...]
real 0m44.576s
user 0m6.239s
sys 0m4.407s
Yarn is used for the package manager. NPM is used to install nest cli globally (npm i -g @nestjs/cli
):
Software | Version | Running in container | Running on W10 host |
---|---|---|---|
NPM | 8.1.2 | X | |
NodeJS | v16.13.1 | X | |
Yarn | 1.22.15 | X | |
Typescript | 4.5.2 | X | |
Nest | 8.1.6 | X | |
Visual Studio Code | 1.63.2 | X | |
Docker Desktop | 4.3.1 | X |
It looks like the line const localCommandLoader = local_binaries_1.loadLocalBinCommandLoader();
in /usr/local/share/npm-global/bin/nest
is causing the delay.
Edit:
Compiling is also very slow. As you can see, it started at 8:57:20 and finished at 9:00:17. And this is compiling the default scaffolding.
[8:57:20 AM] Starting compilation in watch mode...
[8:59:43 AM] Found 0 errors. Watching for file changes.
[Nest] 5197 - 12/23/2021, 9:00:17 AM LOG [NestFactory] Starting Nest application...
[Nest] 5197 - 12/23/2021, 9:00:17 AM LOG [InstanceLoader] AppModule dependencies initialized +67ms
[Nest] 5197 - 12/23/2021, 9:00:17 AM LOG [RoutesResolver] AppController {/}: +42ms
[Nest] 5197 - 12/23/2021, 9:00:17 AM LOG [RouterExplorer] Mapped {/, GET} route +8ms
[Nest] 5197 - 12/23/2021, 9:00:17 AM LOG [NestApplication] Nest application successfully started +8ms
I did the same on WSL:
[10:03:48 AM] Starting compilation in watch mode...
[10:03:53 AM] Found 0 errors. Watching for file changes.
[Nest] 1998 - 12/23/2021, 10:03:54 AM LOG [NestFactory] Starting Nest application...
[Nest] 1998 - 12/23/2021, 10:03:54 AM LOG [InstanceLoader] AppModule dependencies initialized +62ms
[Nest] 1998 - 12/23/2021, 10:03:54 AM LOG [RoutesResolver] AppController {/}: +14ms
[Nest] 1998 - 12/23/2021, 10:03:54 AM LOG [RouterExplorer] Mapped {/, GET} route +6ms
[Nest] 1998 - 12/23/2021, 10:03:54 AM LOG [NestApplication] Nest application successfully started +9ms
For the Docker image I’ve selected the Node.js & TypeScript
image. Would it be better to just use a plain image and install everything manually?
Or is there a way to get the response time of nest
normal again?
2
Answers
TL;DR If you insist on booting into Windows for development but want to use VSCode and dev containers, try doing it all inside a Linux VM as I got a 96% reduction in time taken for key dev task steps.
Summary
I get a 96% reduction on startup / recompile time of a dev-container NestJS TypeScript project on
npm run start:dev
when running in a linux VM inside Windows 10 vs VSCode directly Windows 10 with docker and wsl2. ie 7s vs 2m 50sDev Containers
I think dev containers are great, love using them on github codespaces, but found the experience on Win 10 to be painfully slow.
In a multi developer team dev containers can offer a consistent experience between developers and reduce the risk of different setups on different developers’ machines. But that’s worthless if it takes more than a few seconds to rebuild the app everytime you save a file while running in ‘watch’ mode.
What slows NestJS / TypeScript in Dev Containers
After various investigations I’m convinced the speed penalty is in the dev container accessing the hosts filesystem.
NestJS cli is frustratingly eager to load everything it can do, before it even parses the command line args, so that’s a big hit if filesystem access is slow.
And then the TypeScript compilation is obviously heavily dependent on filesystem speed. So this is the other area that grinds to a halt. Even on a relatively small NestJS project with few additional external dependencies!
What’s fastest
Running Linux inside a VM on my Windows machine, running VSCode and docker all inside that VM meant that the filesystem access between the commands running inside the dev container (in docker inside the linux VM) can access the code ‘hosted’ on the linux VM very quickly.
Comparison Table
Browser
Win10 remote
on Win 10 with WSL2
in Linux VM
in Win 10
npx nest i
npm run start:dev
startupnpm run start:dev
update a filerm -rf node_modules ; time npm install
Setups used:
To get an active-developer experience, I ran each command a few times until the timing settled down and recorded the most representative time…
time npx nest i
npm run start:dev
startupLOG [NestFactory] Starting Nest application...
npm run start:dev
update a fileLOG [NestFactory] Starting Nest application...
rm -rf node_modules ; time npm install
I have been experiencing this as well and wanted to expand on the info above based on my experience. VS Code has a WSL extension which lets you open WSL folders in code which allows you to see better performance on the file system. See https://code.visualstudio.com/docs/remote/wsl for reference. Here are the steps I used to be able to make it work:
code .
It is also possible to do it from the VS Code interface as well as noted in the VS Code post.This feels a little convoluted but it seems this is the supported way for now based on what I read. Perhaps in the future the WSL2 to Windows file system interface will be improved to a point where this is not necessary.
Happy to hear any feedback or update this based on other’s experiences.