Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tailwindcss-intellisense spawns ripgrep process that chews CPU on a project without Tailwindcss #986

Open
jdoss opened this issue Jun 24, 2024 · 13 comments · May be fixed by #1242
Open

tailwindcss-intellisense spawns ripgrep process that chews CPU on a project without Tailwindcss #986

jdoss opened this issue Jun 24, 2024 · 13 comments · May be fixed by #1242
Labels
question Further information is requested

Comments

@jdoss
Copy link

jdoss commented Jun 24, 2024

What version of VS Code are you using?

$ code --version
1.90.2
5437499feb04f7a586f677b155b039bc2b3669eb
x64

What version of Tailwind CSS IntelliSense are you using?

v0.10.5

What version of Tailwind CSS are you using?

No tailwind in my current project.

What package manager are you using?

n/a

What operating system are you using?

Fedora Linux 40 with /home as a BTRFS subvolume on a local NVMe drive.

Tailwind config

N/A

VS Code settings

{
    "python.defaultInterpreterPath": "/bin/python",
    "workbench.startupEditor": "none",
    "application.shellEnvironmentResolutionTimeout": 30,
    "editor.minimap.enabled": false,
    "workbench.colorTheme": "Monokai Pro (Filter Machine)",
    "workbench.iconTheme": "Monokai Pro (Filter Machine) Icons",
    "editor.mouseWheelZoom": true,
    "files.trimTrailingWhitespace": true,
    "editor.renderWhitespace": "all",
    "[python]": {
        "editor.detectIndentation" : false,
        "editor.insertSpaces": true,
        "editor.tabSize": 4,
        "editor.formatOnType": true,
        "editor.codeActionsOnSave": {
            "source.fixAll": "explicit",
            "source.organizeImports": "explicit"
        },
        "editor.defaultFormatter": "ms-python.black-formatter"
    },
    "editor.multiCursorModifier": "ctrlCmd",
    "redhat.telemetry.enabled": false,
    "editor.fontSize": 20,
    "editor.tabSize": 2,
    "files.insertFinalNewline": true,
    "cSpell.ignoreWords": [
        "vofhoa"
    ],
    "files.associations": {
        "*.nomad": "hcl",
        "*.toml": "toml",
        "*.ign": "json",
        "*.jinja": "jinja",
        "*.j2": "jinja-yaml",
        "*.bu": "jinja-yaml"
    },
    "vs-kubernetes": {
        "vs-kubernetes.minikube-show-information-expiration": "2024-01-16T23:50:49.632Z",
        "vs-kubernetes.crd-code-completion": "disabled"
    },
    "editor.acceptSuggestionOnEnter": "on",
    "editor.quickSuggestionsDelay": 50,
    "editor.find.autoFindInSelection": "never",
    "editor.autoIndent": "full",
    "window.closeWhenEmpty": true,
    "editor.emptySelectionClipboard": true,
    "files.encoding": "utf8",
    "editor.detectIndentation": true,
    "editor.dragAndDrop": true,
    "go.toolsManagement.autoUpdate": true,
    "editor.codeActionsOnSave": {},
    "[hcl]": {},
    "emeraldwalk.runonsave": {
        "commands": [
            {
                "match": "\\.nomad",
                "cmd": "nomad fmt ${file}"
            }
        ]
    },
    "python.terminal.activateEnvInCurrentTerminal": true,
    "python.analysis.fixAll": [],
    "terminal.integrated.sendKeybindingsToShell": true,
    "[jinja-html]": {},
    "editor.rulers": [
        119
    ],
    "yaml.schemas": {
        "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml"
    },
    "yaml.customTags": [
        "!ENV scalar",
        "!ENV sequence",
        "tag:yaml.org,2002:python/name:material.extensions.emoji.to_svg",
        "tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji",
        "tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format"
    ],
    "editor.defaultFormatter": "ms-python.black-formatter",
    "inference.model": "custom",
    "editor.formatOnSave": true,
    "git.openRepositoryInParentFolders": "never",
    "mypy.targets": [
        "app"
    ],
    "docker.dockerPath": "podman",
    "docker.environment": {
        "DOCKER_HOST": "unix:///run/user/1000/podman/podman.sock"
    },
    "settingsSync.ignoredSettings": [
        "-docker.environment",
        "-docker.dockerPath"
    ],
    "docker.networks.groupBy": "NetworkName",
    "notebook.defaultFormatter": "ms-python.black-formatter",
    "python.REPL.sendToNativeREPL": true,
    "explorer.fileNesting.patterns": {
        "*.ts": "${capture}.js",
        "*.js": "${capture}.js.map, ${capture}.min.js, ${capture}.d.ts",
        "*.jsx": "${capture}.js",
        "*.tsx": "${capture}.ts",
        "tsconfig.json": "tsconfig.*.json",
        "package.json": "package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb",
        "*.sqlite": "${capture}.${extname}-*",
        "*.db": "${capture}.${extname}-*",
        "*.sqlite3": "${capture}.${extname}-*",
        "*.db3": "${capture}.${extname}-*",
        "*.sdb": "${capture}.${extname}-*",
        "*.s3db": "${capture}.${extname}-*"
    }
}

Describe your issue

If I enable the tailwindcss-intellisense extension and launch VS Code in a project directory that does not have any TailwindCSS code (AFAIK) the extension spawns a rg process that uses 1000%+ CPU.

jdoss@sw-0608:~/Documents/projects$ ps aux |grep tailwind
jdoss     561108  0.3  0.0 1186094516 84208 ?    Sl   11:03   0:00 /usr/share/code/code /home/jdoss/.vscode/extensions/bradlc.vscode-tailwindcss-0.11.77/dist/tailwindServer.js --node-ipc --clientProcessId=476605
jdoss     561169  0.3  0.0 1186094516 83532 ?    Sl   11:03   0:00 /usr/share/code/code /home/jdoss/.vscode/extensions/bradlc.vscode-tailwindcss-0.11.76/dist/tailwindServer.js --node-ipc --clientProcessId=458090
jdoss     561201  0.5  0.0 1186094516 85776 ?    Sl   11:03   0:00 /usr/share/code/code /home/jdoss/.vscode/extensions/bradlc.vscode-tailwindcss-0.11.75/dist/tailwindServer.js --node-ipc --clientProcessId=178375
jdoss     563488 1190  0.0  95584 12800 ?        Sl   11:04   2:26 /usr/share/code/resources/app/node_modules.asar.unpacked/@vscode/ripgrep/bin/rg --files --hidden --case-sensitive --no-require-git -g **/{tailwind,tailwind.config,tailwind.*.config,tailwind.config.*}.{js,cjs,ts,mjs} -g !**/.git -g !**/.svn -g !**/.hg -g !**/CVS -g !**/.DS_Store -g !**/Thumbs.db -g !/{**/.git,**/.svn,**/.hg,**/CVS,**/.DS_Store,**/Thumbs.db,**/.git/**,**/node_modules/**,**/.hg/**,**/.svn/**} --no-ignore --follow --no-config --no-ignore-global

jdoss@sw-0608:~$ cd /proc/563488/cwd/
jdoss@sw-0608:.../563488/cwd$ ls -lah
total 12K
drwxrwxr-x. 1 jdoss jdoss  122 Jun 18 13:05 .
drwxr-xr-x. 1 jdoss jdoss 2.0K Mar  8 12:40 ..
drwxr-xr-x. 1 jdoss jdoss  258 May 29 17:01 apps
drwxr-xr-x. 1 jdoss jdoss  278 Jun 18 13:00 data
drwxr-xr-x. 1 jdoss jdoss  144 Jun 18 13:03 .git
-rw-r--r--. 1 jdoss jdoss   15 Jun 18 13:00 .gitignore
-rw-r--r--. 1 jdoss jdoss 1.1K May  3 15:14 LICENSE
-rw-r--r--. 1 jdoss jdoss    0 May  3 15:22 README.md
drwxr-xr-x. 1 jdoss jdoss   38 May  3 16:32 scripts
-rwxr-xr-x. 1 jdoss jdoss  324 May  8 16:42 selfhost
drwxr-xr-x. 1 jdoss jdoss    0 May  3 16:14 template

This project is an private one that I use to manage container apps on my workstation. It has a data directory that container applications like home assistant, paperless, gitea etc use as volume mounts.

jdoss@sw-0608:~/.../projects/data$ ls -lah
total 4.0K
drwxr-xr-x. 1 jdoss jdoss 278 Jun 18 13:00 .
drwxrwxr-x. 1 jdoss jdoss 122 Jun 18 13:05 ..
drwxr-xr-x. 1 jdoss jdoss  44 May  6 10:08 coredns
drwxr-xr-x. 1 jdoss jdoss  18 May 10 16:17 echoserver
drwxr-xr-x. 1 jdoss jdoss  44 May  6 10:22 gitea
-rw-r--r--. 1 jdoss jdoss  14 Jun 18 13:00 .gitignore
drwxr-xr-x. 1 jdoss jdoss  72 May  6 16:06 homeassistant
drwxr-xr-x. 1 jdoss jdoss  50 May  6 16:44 jellyfin
drwxr-xr-x. 1 jdoss jdoss 184 May  8 12:02 lame
drwxr-xr-x. 1 jdoss jdoss  34 May  7 12:27 n8n
drwxr-xr-x. 1 jdoss jdoss 146 May  7 15:18 paperless
drwxr-xr-x. 1 jdoss jdoss  46 May  6 15:07 stepca
drwxr-xr-x. 1 jdoss jdoss  90 May  9 15:20 temporal
drwxr-xr-x. 1 jdoss jdoss 248 Jun 21 16:38 traefik
drwxr-xr-x. 1 jdoss jdoss  26 May  8 00:14 vaultwarden
drwxr-xr-x. 1 jdoss jdoss  80 May  8 02:15 windmill

Some of these projects do have .ts and .js files in this directory so maybe it is choking on watching all of those files? Maybe the extension should check for a tailwind config and only spawn the rg process if it knows that TailwindCSS is being used in the project root?

@thecrypticace
Copy link
Contributor

Looks like Dev Container's had a similar issue that they fixed / worked around: microsoft/vscode-remote-release#9738

It's not open source (that I can see) so I don't know exactly what they did to fix it but one of the comments gave me potential ideas to go on. I'll see what I can come up with.

Thanks for reporting this!

@thecrypticace
Copy link
Contributor

Okay so a couple of questions:

  • Are you using PNPM for any of those projects?
  • If you take that manual rg command from ps and run it yourself in the same working directory without the --follow flag does it complete quickly?
  • Do you know what kind of mounts you are using in Docker? Are they actual volume mounts, bindfs, or something else?
  • What storage driver are the mounts using?

You're on an NVMe SSD so I doubt drive speed is not even remotely in play here. I wonder if Docker is doing something weird with those directories that causes directory listing and/or other file operations to slow down.

@thecrypticace thecrypticace added the question Further information is requested label Jun 24, 2024
@robcresswell
Copy link

I think I've found something similar in my project. It's a Python data project that as part of normal operation will install tens or hundreds of node projects. There's no tailwind install or config in the project root though, is there a sensible way I can disable it? I have the plugin installed for other projects I work on 😃

@Ev357
Copy link

Ev357 commented Aug 29, 2024

i think i have a similar problem. I noticed when my laptop suddenly started crashing. When i looked into my processes:
image
I'm using v0.0.24 with neovim (btw).
image
I just opened a index.vue file in an empty folder.

@zaaack
Copy link

zaaack commented Sep 4, 2024

same here

@adamhamlin
Copy link

Same issue

@BFranse
Copy link

BFranse commented Dec 6, 2024

I have the same issue happening. On the latest version (0.12.15) when enabled, it spawns tens of rg processes consuming all cpu on an M3 pro. What I did to temporarily resolve it for now, is install 0.12.11, which seems to not have this issue.

If I can provide some more info to help troubleshoot the issue, please let me know how and I'll happily provide it.

@decafdennis
Copy link

decafdennis commented Jan 17, 2025

Same. After installing this extension and opening a (large) codebase that doesn't use Tailwind, it spawns many of the same process:

/Applications/Visual Studio Code.app/Contents/Resources/app/node_modules/@vscode/ripgrep/bin/rg --files --hidden --case-sensitive --no-require-git -g **/{tailwind,tailwind.config,tailwind.*.config,tailwind.config.*}.{js,cjs,ts,mjs,mts,cts} -g !**/.git -g !**/.svn -g !**/.hg -g !**/CVS -g !**/.DS_Store -g !**/Thumbs.db -g !/{**/.git,**/.svn,**/.hg,**/CVS,**/.DS_Store,**/Thumbs.db,**/.git/**,**/node_modules/**,**/.hg/**,**/.svn/**} --no-ignore --follow --no-config --no-ignore-global

The number of processes keeps growing and growing until eventually my computer becomes very unhappy.

Using version 0.12.18 of the extension and 1.96.4 of VSCode.

@thecrypticace
Copy link
Contributor

So we don't spawn these processes directly. They are spawned by VSCode — likely due to registering watch patterns. But I can't think of a reason these would spawn a bunch or use 100% CPU.

@BFranse @decafdennis Would it be possible to provide access to a project that reproduces the issue (even if privately via GitHub?)

@decafdennis
Copy link

@decafdennis Would it be possible to provide access to a project that reproduces the issue (even if privately via GitHub?)

Sorry, I can't... if you have any quick pointers on how to debug, I'd be happy to try.

The extension works fine in the repo where I need it, though, so for now I'm happy to just enable it on a workspace-by-workspace basis.

@BFranse
Copy link

BFranse commented Jan 23, 2025

So we don't spawn these processes directly. They are spawned by VSCode — likely due to registering watch patterns. But I can't think of a reason these would spawn a bunch or use 100% CPU.

@BFranse @decafdennis Would it be possible to provide access to a project that reproduces the issue (even if privately via GitHub?)

Sorry, I can't. Like @decafdennis I'm happy to try and provide any info you'd need.

Edit: I was writing up all my details and wanted to attach a video, and it doesn't seem to cause issues anymore now.
It did earlier in the morning though. I did fix a settings/config thing about linting and formatting for another extension this morning, but I'm not sure if they could be related.

@thecrypticace
Copy link
Contributor

By any chance does using the tailwindCSS.experimental.configFile resolves anyone's issues with the runaway ripgrep process?

I've also seen some reports in other extensions that the ripgrep process can have problems when symlinks are involved. Could that be the case here?

@thecrypticace
Copy link
Contributor

Note: This investigation was based on the current main branch of VSCode (ce3d246164dc513218f9e612cc69d7ea8c168c52 when I started writing this) but I don't think many of these details have changed significantly in a while.

I just spent several hours tracking things through VSCode's source. A number of things result in a ripgrep process being spawned like searching for files in the sidebar, clicking file URLs in terminal (if my reading was correct), searching through notebooks, etc…

However, the only extension APIs that eventually invoke ripgrep are:

  • Workspace.findFiles
  • Workspace.findTextInFiles (this is a proposed extension API)
  • workspaceContains in package.json

Our extension ONLY uses Workspace.findFiles. We don't use Workspace.findTextInFiles at all and we can't use workspaceContains because determining whether or not our LSP should start is a bit more complicated so we unconditionally start the extension and do some work to figure out if we need to start out LSP. The LSP itself then does additional scanning to determine if any Tailwind CSS projects exist in the current workspace.

After the extension starts we:

  • Search open workspaces for files (using Workspace.findFiles)
  • Register file watchers for any open workspaces that would match the files we're looking for
  • Use this information to boot the language server
  • Set up other language server related stuff (e.g. class sorting, user visible error messages, etc…)

Notably, file watchers DO NOT invoke ripgrep. These are eventually handled by either Parcel Watcher or Node's built-in file system watcher. So, as far as I can tell, the only invocation of ripgrep caused by our extension is our up to two calls to Workspace.findFiles per workspace folder. And most projects only have one workspace folder unless you've explicitly set up a multi-root workspace.

The two calls we make are for these two globs

  • **/{tailwind,tailwind.config,tailwind.*.config,tailwind.config.*}.{js,cjs,ts,mjs,mts,cts} — looks for any v3-style tailwind configs
  • **/*.{css,scss,sass,less,pcss} - looks for CSS files. We do some additional processing of these files to determine if we need to start the language server.

Microsoft has a wiki note specifically about excessive ripgrep CPU usage.

This article seems to call out a few big causes:

  • Symlink traversal
  • Excessively large projects — I don't know what a good threshold for this is but I just tested a monorepo with 1000 packages and ~200k files in it (I'm on an M3 Max tho so I have a fast CPU and SSD).
  • Windows Defender (or other antivirus software)

Solution

It looks like there's not a whole lot we can do solve the problem. However, we do have the ability to cancel the search if it takes too long. While I was never able to reproduce ripgrep running "forever" I have reproduced it running for several seconds on the 1000 pkg / 200k file project I mentioned above. I've opened a PR to cancel searches after ~15s in #1242. I'm hoping this will actually terminate any "stuck" processes but testing this scenario doesn't seem to be possible for me.

Workarounds

Aside from the PR there are some workarounds that could potentially speed up or entirely eliminate the searches for some people:

Disable following symlinks while searching

This advice is given in the above linked wiki note. Disabling this appears to speed up ripgrep significantly in some of my tests. Add the following to your settings. This is especially important if you use PNPM and are seeing this in projects:

"search.followSymlinks": false

Use the tailwindCSS.experimental.configFile setting

For projects that use Tailwind CSS, you can use the tailwindCSS.experimental.configFile setting and we'll skip the file searching in the workspace folder with that setting. The Language Server itself even skips over a good bit of file traversal when this setting is given.

Note: We do still register file watchers right now but these don't appear to pose a problem from what I can tell. In any case, this is something I'm likely to clean up in the future.

For projects/workspaces that do not use Tailwind CSS

If you can't disable search.followSymlinks or if it doesn't resolve the problem I recommend disabling our extension on a per-workspace basis.

I thought about adding a setting that would effectively disable the extension for a workspace but this does not seem ideal because if you're experiencing these issues you'd probably want to set it globally. However, if you do that then you'd have to re-enable it on a per-workspace basis. So it seems fine to essentially just do that but with the extension as a whole and it requires no changes to support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants