skip to Main Content

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


  1. 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 50s

    Dev 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

    Activity Codespaces
    Browser
    Codespaces
    Win10 remote
    VSCode + Win Docker
    on Win 10 with WSL2
    VSCode + docker
    in Linux VM
    in Win 10
    npx nest i 1.16s 1.16s 14.2s 1.12s
    npm run start:dev startup 10s 8s 170s 7s
    npm run start:dev update a file 3s 2s 38s 2s
    rm -rf node_modules ; time npm install 30s 28s 85s 27s

    Setups used:

    • Codespaces
      • 2core 4GB instance
    • Win 10
      • AMD Ryzen 7 3700X 8 Core @ 4.16GHz
      • 64GB 2400MHz RAM
      • 1TB SSD
      • Internet: 27Mb down / 5Mb up
    • Linux VM (inside Win 10 above)
      • VMware 16.2.3
      • Ubuntu 22.04
    • dev container is the recommended Node.js & Typescript container with VARIANT: "16-bullseye"
      • with mariadb server running inside

    To get an active-developer experience, I ran each command a few times until the timing settled down and recorded the most representative time…

    • anything that doesn’t use ‘time’ in the command was done by hand and so has a +/- 1sec error
    • time npx nest i
      • the time the command shows at the end
    • npm run start:dev startup
      • timing is from hitting enter to the first log of LOG [NestFactory] Starting Nest application...
    • npm run start:dev update a file
      • timing is from saving an update to a watched file, to the next log of LOG [NestFactory] Starting Nest application...
    • rm -rf node_modules ; time npm install
      • just another filesystem dependent task to compare the environments
      • the time the command shows at the end
    Login or Signup to reply.
  2. 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:

    • Install Ubuntu 20 from the Microsoft Store for a WSL distro. You can install it other ways I believe. I tried 22 and it did not work but not sure if that was because I did something else wrong so you could try it and see.
    • Enable WSL integration for the new distro with Docker Desktop. Reference https://docs.docker.com/desktop/windows/wsl/ for some information on this.
    • Install the WSL extension for VS Code. See first link above.
    • As noted in both links above the way to start is open up a WSL terminal, cd to the directory you want to run VS Code in and type code . It is also possible to do it from the VS Code interface as well as noted in the VS Code post.
    • From there if you have your .devcontainer folder already setup you can reopen the folder in a dev container and away you go!
    • If you need to access any of the files through Windows you can go to the wsl$ network path and access them there.

    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search