🐳

Dev Containers のパフォーマンス改善

2024/03/26に公開

Visual Studio Code の Dev Containers がとても便利でいろいろなプロジェクトで使っているのですが、パフォーマンス周りで何度か嵌ったので、改善方法を記載しておきます。

なお、下記公式ドキュメントでも、パフォーマンス改善に関してまとめられていますので、一度目を通すことをお勧めします。

本ページでは、実際に自分が試した内容と、それでどれくらい改善したかを記載しておきます。

サンプルプロジェクト

実際どれくらい改善するかを確認するために、NestJSの素振りをしていたプロジェクトを利用します。
DBとしてPostgreSQLを使い、Docker Composeで一緒に起動するような形になっています。

下記のコードが、改善前のコードになります。(branch切ってます)

手元の環境(Windows 10)では、 npm run test で200秒以上かかる状態です。

Test Suites: 2 passed, 2 total
Tests:       29 passed, 29 total
Snapshots:   0 total
Time:        219.663 s, estimated 228 s

改善方法

Dev Containers では、ローカルのフォルダをコンテナ上のフォルダに bind mount するのですが、ここで大量のファイルの書き込みや参照が発生すると、パフォーマンスを劣化させる原因となることがあるようです。

このディスク周りを改善することが、Dev Containers でのパフォーマンスを改善することとなります。

(1) named volume を利用する

node_modulesのような、Gitで管理はしないが大量のファイルの読み書きが走るようなフォルダをDockerの named volume とすることで、ローカルフォルダとの bind mount の対象から外せることとなり、性能を改善することができます。

volumesで named volume を定義し、それをnode_modulesにマウントします。
以下はdocker-compose.yamlで定義している場合の例です。

    volumes:
      - ..:/workspaces/app:cached
+     - app-node-modules:/workspaces/app/node_modules
volumes:
  postgres-data:
+ app-node-modules:

以下のbranchが上記を設定したものになります。

コンテナを一つしか利用しておらず、devcontainer.json のみで定義している場合には、mountsプロパティを利用して設定します。

"mounts": [
    "source=${localWorkspaceFolderBasename}-node-modules,target=${containerWorkspaceFolder}/node_modules,type=volume"
]

この状態で npm run test を実行すると、200秒以上かかっていたものが10秒台まで改善しました。

Test Suites: 2 passed, 2 total
Tests:       29 passed, 29 total
Snapshots:   0 total
Time:        13.279 s

(2) ファイルを WSL2 上に配置する

ローカルがWindowsの場合、WSL2 でのファイルシステム上にファイルを配置し、そこからVisual Studio Codeを起動することでもパフォーマンスが改善します。

WSL2 のターミナル上で所定のフォルダに移動し、code . とすることで、WSL上でVisual Studio Codeを開くことができます。

node_modulesを named volume にする前の状態で、npm run test で10秒を切るようになりました。

Test Suites: 2 passed, 2 total
Tests:       29 passed, 29 total
Snapshots:   0 total
Time:        9.395 s, estimated 10 s

node_modulesを named volume にした状態でも、ほとんど変わりません。(named volume に置いていても、WSL2上でも変わらなそう)

Test Suites: 2 passed, 2 total
Tests:       29 passed, 29 total
Snapshots:   0 total
Time:        9.435 s, estimated 10 s

ただ、全体をWSL2に載せることで、node_modulesだけを named volumne に置いた時より明らかに早くなるので、できるだけWSL2に載せるのが良いと思います。

まとめ

  1. Gitで管理しない&書き込み/読み込みが多く発生するようなフォルダは、 named volume に置くことでパフォーマンス改善になる
    • node_modulesのような依存ライブラリを配置するフォルダ
    • ビルド後のファイル群を配置するフォルダ
  2. ローカルがWindows上ならば、WSL2上にファイルを配置し、WSL2側でVisual Studio Codeで開くことで、さらなる改善が見込める

Discussion