VSCodeが異常に重い時の対処法
表題のとおりCPU使用率が異常に高くなる現象に遭遇し、IDE設定の最適化で劇的に改善できたので対応方法をまとめました。
参考までに、筆者の環境では以下の改善が見られました。
- ホスト(Mac)のCPU使用率:約85%→20%前半
- AWS CDK(IaC)の
cdk synthコマンド:30分→5分
結論
アクティビティモニタを確認してCodeHelperプロセスによるCPU使用率が高かったり、rgというプロセスが大量に生成されていたりしたら、このケースに該当するはずです。
ライブラリ等が生成するファイル群が検索インデックスの作成対象になっており、ファイルが頻繁に追加・更新されることでインデクシングが追いつかなくなっている可能性が高いです。
VSCodeの場合は以下を参考に
settings.jsonのfiles.watcherExcludeとsearch.excludeの設定を見直しましょう。
{
// ご自分の環境に合った設定を導入してください
"files.watcherExclude": { // ファイル監視から除外するファイル
"**/.git/**": true, // Gitリポジトリ
"**/node_modules/**": true, // Node.jsのパッケージ
"**/dist/**": true, // ビルド成果物
"**/build/**": true, // ビルド成果物
"**/coverage/**": true, // カバレッジレポート
"**/.aws-sam/**": true, // AWS SAMのビルド成果物
"**/.next/**": true, // Next.jsのビルド成果物
"**/.pnpm/**": true, // pnpmの仮想ストア
"**/pnpm-lock.yaml": true, // pnpmのロックファイル
"**/cdk.out/**": true, // AWS CDKのビルド成果物
},
"search.exclude": { // 検索から除外するファイル(ついでに検索時のパフォーマンス向上)
"**/.git/**": true,
"**/node_modules/**": true
... 省略 ...
}
}
本題から逸れますがcdk synthやcdk deployコマンドの場合は--verboseオプションで詳細を確認するのも手です。
SSOログイントークンの期限切れで処理が完了しないケースなどもあり--verboseだと表示してくれるためです。
詳細
最近、AWS CDKを使用しているプロジェクトで、以下のような症状に悩まされていました。
- 長くても数分のはずのCDK synth(デプロイ準備)が、30分待っても終わらない
- IDE全体が重く、タイピング操作がもたつく
プロジェクトサイズもそれほど大きくないなのに、なぜこんなに重いのか…という状況でした。
原因調査
Macのアクティビティモニタを確認すると、マシンのCPU使用率が異常に高くなっていることに気づきました。
そこでVSCodeでCPUの稼働率が張り付くんやが!?を参考に"search.followSymlinks": falseを設定してみたのですが、私のケースでは改善が見られませんでした。
改めてプロセス名に目を向けると、CodeHelperのCPU使用率が高かったり、rgプロセスが大量に生成されたりしていることが判明しました。
CodeHelperプロセスを調べると、VSCodeのCodeHelperのCPU使用率が異様に高いときの対処法という記事を見つけました。
ここではVSCodeの標準機能を使って、拡張機能が悪さしていないかを二分探索的に調べましたが、残念ながら該当なしでした。
次に後者のrgプロセスについてGeminiに聞いてみると、以下のような回答が得られました。
ripgrep(コマンド名は rg)という、非常に高速なテキスト検索ツールです。
なぜ動いているのか: 主に Visual Studio Code (VS Code) などのエディタが、プロジェクト内のファイルから特定の文字列を探したり、ファイルをインデックス(目次)化したりするために裏側で動かしています。
ここでやっと「cdk synthはCDKがCloudFormationのテンプレートを生成するコマンド→テンプレート関連のファイルを大量に生成している→rgプロセスが大量に生成されることと関連していそうだ」と気づきます。
もう一度Geminiに質問してみると、やはりそれらしい答えが返ってきました。
AWS CDKのデプロイ前後で
rg(ripgrep)プロセスが暴走し、CPU使用率が跳ね上がる現象は、VS Codeのファイル監視(Watcher)と検索機能が、CDKの生成する大量のキャッシュファイルに反応してしまうことが主な原因です。考えられる主な原因
cdk.outディレクトリの膨張
cdk deployを実行すると、プロジェクト直下にcdk.outというディレクトリが生成(または更新)されます。ここにはクラウドフォーメーションのテンプレートや、Lambda関数のデプロイパッケージ(ZIP)などが大量に生成されます。- VS Codeのripgrep (
rg) によるスキャン
VS Codeは、プロジェクト内のファイルが更新されると、検索インデックスの更新やシンボリックリンクの解析のためにrgプロセスを立ち上げます。cdk.out内の大量のバイナリや一時ファイルをrgがスキャンしようとして負荷が爆発します。- シンボリックリンクの循環
CDKやNode.jsのプロジェクトではnode_modulesなどでシンボリックリンクが多用されます。VS Codeの設定で「シンボリックリンクを追跡する」が有効になっていると、rgが無限ループに近いスキャンを行い、CPUを使い切ることがあります。
解決策
原因がわかったので、VSCodeの検索インデックスからこれらのディレクトリを除外する設定を追加しました。
それが冒頭に記載したsettings.jsonのfiles.watcherExcludeとsearch.excludeです。
settings.jsonのサンプル設定(再掲)
{
// ご自分の環境に合った設定を導入してください
"files.watcherExclude": { // ファイル監視から除外するファイル
"**/.git/**": true, // Gitリポジトリ
"**/node_modules/**": true, // Node.jsのパッケージ
"**/dist/**": true, // ビルド成果物
"**/build/**": true, // ビルド成果物
"**/coverage/**": true, // カバレッジレポート
"**/.aws-sam/**": true, // AWS SAMのビルド成果物
"**/.next/**": true, // Next.jsのビルド成果物
"**/.pnpm/**": true, // pnpmの仮想ストア
"**/pnpm-lock.yaml": true, // pnpmのロックファイル
"**/cdk.out/**": true, // AWS CDKのビルド成果物
},
"search.exclude": { // 検索から除外するファイル(ついでに検索時のパフォーマンス向上)
"**/.git/**": true,
"**/node_modules/**": true
... 省略 ...
}
}
各設定の意味は、以下のとおりです。
| 設定項目 | 用途 |
|---|---|
files.watcherExclude |
ファイル監視(変更検知)から除外する |
search.exclude |
検索(Grepなど)から除外する |
特に files.watcherExclude が重要で、これを設定することでIDEが不要なファイルの変更監視を行わなくなり、CPU使用率が大幅に改善されます。
私の場合は"**/cdk.out/**": true,の効果が大きく、cdk synthで生成されるファイル群をインデクシング対象外にすることでCPU負荷が激減して問題が解決しました。
同様にご自身の環境で生成されるキャッシュファイルを対象外にすることで、問題が解決できるはずです。
修正前後の様子
修正前

大量のrgプロセスが生成され、CPU使用率が高い(画面外でCode Helperも稼働)
修正後

rgプロセスが生成されなくなり、CPU使用率が大きく低下
最後に
余談ですが「必要以上の操作をしない・させない」という考え方はCI/CDやセキュリティ対策など様々に通じるものがあり、応用が効きそうだと感じました。
基本的ですが
- Dockerfileに余計なファイルをコピーしないことでビルド時間を短縮する(
.dockerignoreの利用含む) - 不要な権限を持たせないことで攻撃を受けるリスクを狭める
などに繋がるので今後も意識していきたいです。
また後からわかったのですが、CodeHelperプロセスは
VSCode は、整形、補完、バリデーションを行うためにファイルを監視しています。
その仕組みが、CodeHelper というプロセスです。
ということらしく、こちらにも解決策が載っていました。
Discussion