这是我认为需要注意的关于我使用 Svelte 语言服务器 (SLS) 的经验的某种文档。
在我中等规模的 Svelte 项目中,我决定尝试使用 Svelte Atom 扩展(已证明 VS Code 在这个问题上是相同的,这是有道理的——这不是编辑器的错)。 经过几分钟的编码后,我注意到严重的性能下降和系统冻结。 事实证明,SLS 进程使用了多达 2 GB 的 RAM。 将项目分开后,我发现导致如此大量内存消耗的文件是/jsconfig.json
和/__sapper__/*
。 值得注意的是,当时我同时编译了开发和生产版本,因此__sapper__
文件夹的大小是其两倍。
jsconfig.json
有一个特别有趣的领域:
{
"exclude": ["node_modules", "dist"]
}
事实证明,SLS 以某种方式尊重这个领域,因为:
jsconfig.json
使内存消耗达到可接受的水平(~350 MB)"__sapper__"
到排除数组中也使内存消耗达到可接受的水平(与删除时相同)我对此的看法:
__sapper__
文件夹中一堆.js
文件的影响? (请注意,在__sapper__/dev/client
中复制粘贴相同的文件并没有增加内存消耗,因此它不是简单地相对于文件数量线性增加)jsconfig.json
究竟如何影响 SLS?jsconfig.json
的用法我真的不知道如何解决这个问题,希望进行某种讨论和可能的文档改进,但请随时关闭它。
语言服务器在后台使用 typescript 的语言服务。 我猜高内存是因为打字稿试图解析所有配置的文件,在jsconfig.json
,要包含在内。 因为typescript语言服务和svelte语言服务器在同一个进程中,不知道typescript语言服务占用了多少内存。
我很好奇你的__sapper__
文件夹有多大。 我的项目有一个jsconfig.json
并设置为包含大约 200 个 js 源文件,并且只使用 150MB。 无法想象你的__sapper__
文件夹是如何导致语言服务器使用超过 2GB 的内存的。
作为参考,这是我的项目的 repo: b339c2a17e @ Innopoints/frontend
我刚刚克隆了它并运行了服务器并得到以下结果:
__sapper__
文件夹包含开发版本时为 490 MB__sapper__
文件夹包含开发和生产版本时为 730 MB您可以尝试自己编译它以尝试重现它(请注意,如果没有环境变量,开发服务器将无法运行,但这没关系,因为无论如何编译都会成功)。 用 Yarn 安装 deps,用yarn dev
编译,然后在 VS Code 中打开任何.svelte
文件。
另外,如果它有任何区别,我使用的是 VSCodium,而不是常规的 VS Code
有没有办法让 SLS 只扫描.svelte
文件? 我不认为.js/.ts
文件与 Svelte 代码分析真正相关。 尤其是那些不是直接导入的,比如__sapper__
文件夹。
如果没有,我很好奇 SLS 在没有jsconfig.json
情况下的行为。 正如我所提到的,删除该文件会使内存消耗恢复到足够的 150 MB。 在 README 中绝对值得一提,因为对于我这个不熟悉 TS 方式的人来说,一个看似完全不相关的jsconfig.json
文件导致如此巨大的差异是一个非常大的惊喜。
是的,我们应该在相关文档中添加一些内容。
需要扫描.ts
/ .js
文件才能为您提供从 svelte 到这些文件的智能感知。 如果不包含这些信息,您将不会获得自动完成/转到定义/悬停信息。
感觉__sapper__
文件夹对 IntelliSense 没有多大用处,所以也许这个忽略甚至可以默认设置并在必要时覆盖
我仍然获得高达 2 GB 的内存使用量,但很难追踪。 当我在该项目中编辑 Svelte 源代码时,感觉它只是在随机时间爆炸。 您可以推荐什么来减少内存消耗?
语言服务器检测svelte 文件并从中遍历文件树。 它还将尊重 jsconfig/tsconfig.xml 文件中的内容。 根据您的经验(“爆炸”,而不是“稳步增加”),我现在的猜测是服务器以某种方式到达了他加载一堆他不应该加载的不相关文件的地步。
您可以查看 VSCode 的 Output->Svelte 并查看是否有任何可疑内容(或者只是将其复制粘贴到此处)
它今天对我来说表现得很好,但是昨天我不得不在关闭 VS Code 后手动终止 svelte 语言工具进程(没有响应 SIGTERM)。
我目前没有更多要添加的内容。
你的项目有多大? 你有tsconfig.json
或jsconfig.json
吗?
@dummdidumm不比工兵模板大多少。 我有一个基本的 tsconfig.json,自从我遇到问题以来就没有改变。
{
"include": [
"src/**/*"
],
"exclude": [
"node_modules/*"
],
"compilerOptions": {
"target": "es2015",
"module": "es2015",
"types": [
"svelte"
]
}
}
因此,您和@illright 都使用工兵并且内存使用量增加。 也许一种模式..将不得不对此进行调查。
@dummdidumm让我知道我是否可以以任何方式协助调查。 也许有一种方法可以通过命令行或其他比在编辑器中摆弄更可重现的方式运行 SLS?
Svelte (Svelte Language Server) stderr FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
Svelte (Svelte Language Server) stderr 1: 0x55d7276c33b6 node::Abort() [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) stderr 2: 0x55d7276c3985 [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) stderr 3: 0x55d723b01817 [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) stderr 4: 0x55d723b017b4 [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) stderr 5: 0x55d723b6f716 [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) stderr 6: 0x55d723b6e538 [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) stderr 7: 0x55d723b6b626 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) stderr 8: 0x55d723b7678e [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) stderr 9: 0x55d723f210b7 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) stderr 10: 0x55d72410e1be [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) stderr 11: 0x55d72440b62b [/usr/lib/electron5/electron]
Svelte (Svelte Language Server) rpc.onClose The RPC connection closed unexpectedly
刚才我再次达到 2.1GB 并 SIGKILLed SLS。 以上可以在Atom的DevTools中看到
哦等等,你在使用 Atom? 您使用的是哪个扩展程序?
@dummdidumm我有 Atom(使用ide-svelte
,手动修改语言服务器版本)和 VSCodium(使用 Svelte Beta)。
这是爆炸发生时VSCodium 的 Svelte 选项卡的
好的,我明白了,谢谢。
似乎在启动后很快就发生了爆炸。
如果您自己在本地使用扩展进行调查,那就太好了! 要在本地为 VSCode(ium,希望应该是相同的)设置扩展,首先卸载它,然后像解释here一样服务。 我的猜测是,在某些时候它应该处理太多文件,可以在这里看到。 如果您在上面(第 72 行)添加控制台日志来记录文件(可能以 10 秒为间隔,例如setInterval(() => console.log(JSON.stringify(Array.from(new Set([...files, ...snapshotManager.getFileNames(), ...svelteTsxFiles]), null , 3)), 10000)
),这可能有助于获得一些见解。
所以看起来snapshotManager.getFileNames()
包含一堆不应该根据jsconfig.json
观看的文件。 它还响应文件更改,因为在构建发生之前它不会从 Sapper 加载任何内容,但从那时起, __sapper__/**/*.js
文件填满了内存
好吧,我想这就是问题的根源。 它解释了突然爆发的原因,因为所有新文件都被添加到跟踪列表中。
是的,大概就是这样。 我认为我们需要调整 TypescriptPlugin 处理 ts/js-onWatchedFilesChange 的方式。 也许像vetur 那样做,只删除旧的东西,不添加新的东西。 或者添加一些最好的猜测路径,如__sapper__ / node_modules / dist
应该被忽略。
我会努力做到这一点。
在此问题解决之前,一个糟糕的解决方法:找到您的 Svelte 扩展目录,打开node_modules/svelte-language-server/dist/src/plugins/typescript/service.js
并注释掉snapshotManager.getFileNames()
:
第 69 行:
// before:
return Array.from(new Set(__spreadArrays(files, snapshotManager.getFileNames(), svelteTsxFiles)));
// after:
return Array.from(new Set(__spreadArrays(files/*, snapshotManager.getFileNames() */, svelteTsxFiles)));
您失去了一些 IntelliSense,但保留了语法突出显示,至少性能不会随机下降。 如果你和我一样,那应该足够了:)
补充@illright所说的内容。 它通常位于 Windows 中的~/.vscode/extensions
或%userprofile%\.vscode
\extensions\
中。
另一种解决方法是转到node_modules/svelte-language-server/dist/src/plugins/typescript/TypeScriptPlugin.js
onWatchFileChanges
下行添加到第 237 行,其中
if (/node_modules|__sapper__|dist/.test(fileName)) {
return;
}
这种方法是问题的根源
我创建了一个 PR #165。 你们可以在调试中尝试一下,看看它是否有所改善?
@jasonlyu123是的,我注意到改进。 有一段时间摆弄我的项目,内存消耗得到控制。 Sapper 重建似乎也不会触发内存溢出。
注意:保持在控制之下 = ~480 MB 峰值。 这足够低,不会影响我的系统,但您可能仍然认为这种高内存消耗。 我的机器上有 8 GB 的 RAM。
痛苦是真的😭
即使我们默认排除__sapper__
,我仍然建议将__sapper__
放在 tsconfig.json/jsconfig.json 的排除中。 因为我们正在使用我们自己的打字稿包。 vscode 使用的 tsserver 可能仍然包含它。
@illright你能检查一下最新的插件版本吗? 现在应该好多了。
VS Code 看起来像往常一样流畅,使用了大约 400 MB 的内存。 有没有可能将 SLS 的更新推送到 Atom 扩展? 这就是我前几天注意到性能下降的地方
@orta正在将 Atom 插件转移到这个 repo 中。 完成此操作后,您应该会获得语言服务器的更新。
@rob-balfre 是否也为您降低了内存使用量? 如果没有,你能指定你的设置吗?
我遇到了同样的问题,将 transpileOnly 添加到打字稿预处理器似乎大大改善了这种情况。
在你的 svelte.config.js
``
const sveltePreprocess = require("svelte-preprocess");
模块.出口 = {
预处理:sveltePreprocess({
打字稿:{
transpileOnly:真,
},
}),
// ...其他苗条选项(可选)
};
我在最近更新 VSCode 后不久也注意到了这一点。 小项目似乎没有那么大的问题(尽管储蓄仍然比平时花费的时间长一点)。 保存将挂起,然后文件将保存并格式化。 之后好像还好。 这仅适用于小型项目。 就像它正在尝试索引项目文件夹或其他东西并被挂断? 具有更多文件等的更大项目最终会挂起并出错。
保存 Svelte 文件时会发生内存使用/错误。 它只是挂起并挂在右下角的这条消息上:
这是 Svelte 输出窗口:
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 0x1143fdbe5 node::Abort() [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
2: 0x1143fdc54 node::Abort() [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
3: 0x11010b237 v8::internal::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*) [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
4: 0x11010b1d7 v8::internal::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*) [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
5: 0x1101500a5 v8::internal::Heap::StartIdleIncrementalMarking(v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
6: 0x110151719 v8::internal::Heap::StartIdleIncrementalMarking(v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
7: 0x11014e3ec v8::internal::Heap::CreateFillerObjectAt(unsigned long, int, v8::internal::ClearRecordedSlots, v8::internal::ClearFreedMemoryMode) [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
8: 0x11014c002 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
9: 0x11015746a v8::internal::Heap::PromotedExternalMemorySize() [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
10: 0x110157851 v8::internal::Heap::PromotedExternalMemorySize() [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
11: 0x110358a5a v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
12: 0x1105e19bf v8::internal::RegExp::CompileForTesting(v8::internal::Isolate*, v8::internal::Zone*, v8::internal::RegExpCompileData*, v8::base::Flags<v8::internal::JSRegExp::Flag, int>, v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::String>, bool) [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
13: 0x110c23139 v8::internal::compiler::ZoneStats::ReturnZone(v8::internal::Zone*) [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
14: 0x110bf293d v8::internal::compiler::ZoneStats::ReturnZone(v8::internal::Zone*) [/Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
<--- Last few GCs --->
al[45813:0x7fe18e004200] 47201 ms: Mark-sweep 4095.0 (4102.8) -> 4094.4 (4103.3) MB, 2004.1 / 0.0 ms (+ 6.4 ms in 18 steps since start of marking, biggest step 5.3 ms, walltime since start of marking 2020 ms) (average mu = 0.146, current mu = 0.005) all[45813:0x7fe18e004200] 50534 ms: Mark-sweep 4095.7 (4103.3) -> 4095.3 (4104.5) MB, 2648.3 / 0.0 ms (+ 668.5 ms in 21 steps since start of marking, biggest step 50.7 ms, walltime since start of marking 3332 ms) (average mu = 0.063, current mu = 0.005)
<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 0x110c23139]
Security context: 0x287bc74e0dd1 <JSObject>
1: keys [0x287bc74c15b1](this=0x287bcb9bfaa1 <Object map = 0x287be02c4cb9>,0x287bc68e8e29 <Object map = 0x287bcfd3aa99>)
2: uvException(aka uvException) [0x287b27f974e1] [internal/errors.js:374] [bytecode=0x287b18cb32e9 offset=424](this=0x287bb6f004b1 <undefined>,0x287bc68e8e29 <Object map = 0x287bcfd3aa99>)
3: handleErrorFromBinding(aka handleError...
[Info - 9:59:17 PM] Connection to server got closed. Server will restart.
[Error - 9:59:17 PM] Request textDocument/formatting failed.
Error: Connection got disposed.
at Object.dispose (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/main.js:904:25)
at Object.dispose (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-languageclient/lib/client.js:74:35)
at LanguageClient.handleConnectionClosed (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-languageclient/lib/client.js:2309:42)
at LanguageClient.handleConnectionClosed (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-languageclient/lib/main.js:155:15)
at closeHandler (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-languageclient/lib/client.js:2296:18)
at CallbackList.invoke (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/events.js:62:39)
at Emitter.fire (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/events.js:121:36)
at closeHandler (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/main.js:240:26)
at CallbackList.invoke (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/events.js:62:39)
at Emitter.fire (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/events.js:121:36)
at IPCMessageReader.fireClose (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/messageReader.js:111:27)
at ChildProcess.<anonymous> (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/messageReader.js:213:45)
at ChildProcess.emit (events.js:208:15)
at ChildProcess.EventEmitter.emit (domain.js:476:20)
at maybeClose (internal/child_process.js:1021:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)
[Error - 9:59:17 PM] Request textDocument/hover failed.
Error: Connection got disposed.
at Object.dispose (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/main.js:904:25)
at Object.dispose (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-languageclient/lib/client.js:74:35)
at LanguageClient.handleConnectionClosed (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-languageclient/lib/client.js:2309:42)
at LanguageClient.handleConnectionClosed (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-languageclient/lib/main.js:155:15)
at closeHandler (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-languageclient/lib/client.js:2296:18)
at CallbackList.invoke (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/events.js:62:39)
at Emitter.fire (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/events.js:121:36)
at closeHandler (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/main.js:240:26)
at CallbackList.invoke (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/events.js:62:39)
at Emitter.fire (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/events.js:121:36)
at IPCMessageReader.fireClose (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/messageReader.js:111:27)
at ChildProcess.<anonymous> (/Users/babycourageous/.vscode/extensions/svelte.svelte-vscode-99.0.44/node_modules/vscode-jsonrpc/lib/messageReader.js:213:45)
at ChildProcess.emit (events.js:208:15)
at ChildProcess.EventEmitter.emit (domain.js:476:20)
at maybeClose (internal/child_process.js:1021:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)
Initialize language server at Code/Project
Trying to load config for Code/Project/src/App.svelte
Initialize new ts service at
这也发生在保存其他文件(.js 等)的这个更大的 Svelte 项目中。 如果我禁用 Svelte Beta,一切都很好(除了现在无法识别 Svelte 文件。
我不想开始一个新问题,因为它似乎与此有关,但如果这无关紧要,绝对可以。
谢谢!
谢谢提供信息。 我还有一些问题要缩小范围:
svelte.plugin.svelte.format.enable
为false
(https://github.com/sveltejs/language-tools/tree/master/packages/svelte-vscode#sveltepluginsvelteformatenable),是否还会出现错误? 或者无论如何输出都充斥着内存错误?tsconfig.json
或jsconfig.json
吗? 如果不这样做,如果添加一个(可以只是一个简单的)会发生什么?嗨@dummdidumm感谢您的快速回复!
首先 - 从今天早上开始,我打开了一些东西来测试你的问题......它似乎已经消失了。 经典的。
这里有一些答案供后人参考:
我们在谈论多少个 svelte/js 文件?
它是在处理项目几秒/分钟后立即发生还是仅在一段时间后发生?
到目前为止,它是立即的。 打开项目、修改文件、保存等情况时有发生。 而且我是在昨天(或前一天)VSCode 更新之后才注意到的。 尽管 Svelte Beta 的保存速度通常比以前的扩展慢(在格式化和保存发生前大约 2-4 秒),如果这有任何用处的话。
如果将 svelte.plugin.svelte.format.enable 设置为 false(https://github.com/sveltejs/language-tools/tree/master/packages/svelte-vscode#sveltepluginsvelteformatenable),是否还会出现错误?
下次我注意到这种情况时,我可以试试这个。 不幸的是,因为刚才它随机停止,我认为它没有任何好处,呵呵。
你有 tsconfig.json 或 jsconfig.json 吗?
在我的任何项目中都没有.tsconfig
或.jsconfig
。 如果您有任何简单的设置要分享,我下次也可以尝试。
所以,总而言之,它消失了,但该死的,如果我们现在不知道这个问题,嘿嘿。
经典😄
我问了jsconfig.json
/ tsconfig.json
问题,因为我们之前有一个类似的错误,语言服务在启动时会加载太多文件,因为它正在文件树的更上方找到另一个配置(在项目文件夹)并使用它 - 尽管现在应该修复。
我将添加一些日志记录以获取启动时以及之后每分钟加载的文件数。
听起来不错 - 如果有任何变化,我会通知你! 我现在正在玩那些> 10个文件项目之一,一切仍然一帆风顺......
我们添加了额外的措施来防止初始文件膨胀。 如果有人仍然遇到高内存使用率,请在此处报告。 否则我将在几周内关闭它。
@dummdidumm关于 Atom 扩展的任何更新?
有关这方面的信息和进展,请参阅 #70。
从 VSCode 观察器中排除__sapper__
停止扩展,因为我的内存不足。