extensions.experimental.affinity 是关键开关,因其能强制分流插件运行位置:0表示仅本地、1表示仅远程、2表示自动(默认且最危险),必须配置在远程服务器的 ~/.vscode-server/data/machine/settings.json 中,配合 files.watcherexclude 才可有效抑制cpu暴涨。

为什么 extensions.experimental.affinity 是关键开关
Remote-SSH 默认把所有插件(尤其是语言服务器、格式化器、LSP 类)全扔到远程运行,vscode-server 进程就变成 CPU 和内存黑洞。这不是插件“太多”的问题,而是 VSCode 没做亲和性调度——它不区分哪些插件必须远程(如依赖系统 Python 环境的 ms-python.python),哪些完全可以本地跑(如主题、Git 图标、Markdown 预览)。extensions.experimental.affinity 就是唯一能强制分流的配置项,数值含义明确:0 = 仅本地,1 = 仅远程,2 = 自动(默认,也是最危险的)。
怎么在远程端正确写 settings.json
这个配置必须写在远程服务器上,路径是 ~/.vscode-server/data/Machine/settings.json,不是你本地的 settings.json。写错位置等于没写。常见错误包括:
- 误改本地
settings.json,对远程负载零影响 - 写进
~/.vscode-server/data/User/settings.json(这是 workspace 级,不生效) - 用中文引号或尾逗号导致 JSON 解析失败,VS Code 会静默忽略整段
推荐最小可用配置:
{"extensions.experimental.affinity": {"*": 0}}
再按需放开个别插件,比如要保留远程 Python 语言服务:
{"extensions.experimental.affinity": {"*": 0, "ms-python.python": 1}}
哪些插件必须设为 1?别瞎猜,看依赖
不是“看着重要”就放远程,而是看它是否强依赖远程环境变量、二进制路径或文件系统权限。典型必须远程的有:
-
ms-python.python:需要调用远程python、pip和 site-packages 路径 -
ms-vscode.cpptools:依赖远程g++、clang、compile_commands.json位置 -
esbenp.prettier-vscode(如果 prettier 配置里用了require远程 node_modules)
而像 bradlc.vscode-tailwindcss、esbenp.prettier-vscode(纯本地 node_modules)、shd101wyy.markdown-preview-enhanced 这类,基本都能安全设为 0。
配合 files.watcherExclude 才算真正压住 CPU
光调 affinity 不够。很多高 CPU 占用实际来自文件监听器——比如 stylelint.vscode-stylelint 默认扫整个工作区,一碰 node_modules 就触发成千上万 fs 事件。必须同步加:
"files.watcherExclude": { "**/node_modules/**": true, "**/dist/**": true, "**/build/**": true, "**/.git/**": true }
注意:**/.git/** 很容易被忽略,但 Git 插件在大型 repo 中频繁 stat .git/index 也会拖慢事件循环。如果项目有 logs/ 或 cache/ 目录,也建议一并 exclude。
真正难的是判断某个插件到底该放哪边——它不报错,只悄悄吃 CPU;你 kill 掉进程,它又自动拉起。最稳的办法永远是:先全设 0,再逐个放开,每放开一个就 ps aux | grep node 看新增进程的命令行参数,确认它真在干该干的事。











