Lag and stuttering when using Tailwindcss LSP
Make sure you have done the following
- [x] Updated to the latest version of
blink.cmp - [x] Searched for existing issues and documentation (try
<C-k>on https://cmp.saghen.dev)
Bug Description
The ui gets laggy when editing html classes when the taiwindcss lsp is active. This was a known issue in nvim-cmp but was resolved somewhat recently. I tried to enable the async option for the lsp source and it helped but there still is lag and stuttering.
The video shows that when typing, the editor lags and then shows the typed word all at once.
https://github.com/user-attachments/assets/9faff883-0856-4961-b93f-27abb3343130
Relevant configuration
sources = {
default = {
'lsp',
'path',
'snippets',
'buffer',
'markdown',
},
providers = {
lsp = {
name = 'LSP',
module = 'blink.cmp.sources.lsp',
async = true,
score_offset = 5,
},
ripgrep = {
module = 'blink-cmp-rg',
name = 'Ripgrep',
async = true,
opts = {
search_casing = '--smart-case',
},
},
markdown = {
name = 'RenderMarkdown',
module = 'render-markdown.integ.blink',
fallbacks = { 'lsp' },
},
},
},
neovim version
v0.11.0
blink.cmp version
v1.2.0
What's your system specs and what operating system are you on? Are you able to reproduce the lag in a repro.lua with just the LSP source enabled (if so, please send it over!)? It takes ~4ms to update the menu with tailwind on my system so it's quite unusual that it's locking up your whole editor.
I'm running NixOS 24.11 and the version of tailwind lsp is 0.14.4. The version of tailwind used in the demo is ^4.
The issue is still present with the following config:
vim.env.LAZY_STDPATH = '.repro'
load(vim.fn.system('curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua'))()
---@diagnostic disable-next-line: missing-fields
require('lazy.minit').repro({
spec = {
{
'saghen/blink.cmp',
-- please test on `main` if possible
-- otherwise, remove this line and set `version = '*'`
-- build = 'cargo build --release',
version = '*',
opts = {
sources = {
default = {
'lsp',
},
},
},
},
{
'neovim/nvim-lspconfig',
config = function()
require('lspconfig').tailwindcss.setup({
capabilities = require('blink.cmp').get_lsp_capabilities(),
})
end,
},
},
})
I have the same issue with the tailwindcss server
Minimal repro:
vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()
---@diagnostic disable-next-line: missing-fields
require("lazy.minit").repro({
spec = {
{
"saghen/blink.cmp",
-- please test on `main` if possible
-- otherwise, remove this line and set `version = '*'`
-- build = 'cargo build --release',
version = "*",
opts = {
sources = {
default = {
"lsp",
},
},
},
},
{
"neovim/nvim-lspconfig",
config = function()
vim.lsp.config("tailwindcss", {
root_dir = function(buf, cb)
local name = vim.api.nvim_buf_get_name(buf)
cb(vim.fs.dirname(name))
end,
})
vim.lsp.enable("tailwindcss")
end,
},
{
"mason-org/mason.nvim",
build = ":MasonUpdate",
opts = {},
},
{
"mason-org/mason-lspconfig.nvim",
dependencies = { "mason.nvim", "nvim-lspconfig" },
opts = {
ensure_installed = {
"tailwindcss",
},
automatic_enable = false,
},
},
},
})
git clone https://github.com/theleop/tailwind-minimalcd tailwind-minimal && npm invim --clean -u minimal.lua a.html "+12"ci"- start typing
bg-orange(or any other tailwind class name )
the blink.cmp UI will stutter
A small profile using https://github.com/stevearc/profile.nvim with the following minimal configuration produces the following resutls
vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()
---@diagnostic disable-next-line: missing-fields
require("lazy.minit").repro({
spec = {
{
"saghen/blink.cmp",
-- please test on `main` if possible
-- otherwise, remove this line and set `version = '*'`
-- build = 'cargo build --release',
version = "*",
opts = {
sources = {
default = {
"lsp",
},
},
},
},
{
"neovim/nvim-lspconfig",
config = function()
vim.lsp.config("tailwindcss", {
root_dir = function(buf, cb)
local name = vim.api.nvim_buf_get_name(buf)
cb(vim.fs.dirname(name))
end,
})
vim.lsp.enable("tailwindcss")
end,
},
{
"mason-org/mason.nvim",
build = ":MasonUpdate",
opts = {},
},
{
"mason-org/mason-lspconfig.nvim",
dependencies = { "mason.nvim", "nvim-lspconfig" },
opts = {
ensure_installed = {
"tailwindcss",
},
automatic_enable = false,
},
},
{
"stevearc/profile.nvim",
config = function()
local should_profile = vim.env.NVIM_PROFILE
if not should_profile then
return
end
require("profile").instrument_autocmds()
if should_profile:lower():match("^start") then
require("profile").start("blink*")
else
require("profile").instrument("blink*")
end
vim.keymap.set("n", "<f4>", function()
local prof = require("profile")
if prof.is_recording() then
prof.stop()
vim.ui.input(
{ prompt = "Save profile to:", completion = "file", default = "profile.json" },
function(filename)
if filename then
prof.export(filename)
vim.notify(("Wrote %s"):format(filename))
end
end
)
else
vim.notify("Starting recording")
prof.start("blink*")
end
end)
end,
},
},
})
After hiding everything under blink.cmp.lib.utils.schedule_if_needed (which I suspect are simply callback waiting and not actual blocking calls), the graph looks like
The first big chunk is blink.cmp.completion.list.fuzzy taking 464 ms. Another big chunk of time is the 240 ms taken by blink.cmp.sources.lsp.hacks.tailwind.process_response
Here's a video where the stutter can be seen. It's more noticeable when autocompleting classes that have a color related do them
https://github.com/user-attachments/assets/c7544683-4d95-4d4c-a2fa-d62349d6248e
I have the same issue. I use latest blink.cmp (1.3.1), latest nvim (0.11.1) and it's running on MacBook Pro M3 Max with latest Macos 15.5.
I believe that I didn't have this issue with nvim-cmp.
Same here, I just migrated to blink.cmp and I'm facing the same issue
Make sure you have done the following
* [x] Updated to the latest version of `blink.cmp`[x] Searched for existing issues and documentation (try `<C-k>` on https://cmp.saghen.dev)Bug Description
The ui gets laggy when editing html classes when the taiwindcss lsp is active. This was a known issue in nvim-cmp but was resolved somewhat recently. I tried to enable the async option for the lsp source and it helped but there still is lag and stuttering.
The video shows that when typing, the editor lags and then shows the typed word all at once. output.mp4
Relevant configuration
sources = { default = { 'lsp', 'path', 'snippets', 'buffer', 'markdown', },
providers = { lsp = { name = 'LSP', module = 'blink.cmp.sources.lsp', async = true, score_offset = 5, }, ripgrep = { module = 'blink-cmp-rg', name = 'Ripgrep', async = true, opts = { search_casing = '--smart-case', }, }, markdown = { name = 'RenderMarkdown', module = 'render-markdown.integ.blink', fallbacks = { 'lsp' }, }, }, },
neovimversionv0.11.0
blink.cmpversionv1.2.0
How did you make tailwind render correctly the colors?
Mine renders all as red
@TheLeoP The schedule_if_needed calls taking a long time appears to have been real, as we were passing the items field in the event data. The last remaining bit to optimize is this process_response it seems.
@Saghen OMG, yes, that was it. I just tested the latest main version (with a minimal.lua similar to the one on https://github.com/Saghen/blink.cmp/pull/1830#issuecomment-2923900014 , changing the branch to main) and there is no stuttering at all. Thank you so much for everything :D.
For the sake of completeness, this is what a flamegraph of two completions (as in typing the start of a word, going through the list on completions and selecting one of them, twice) using the same minimal setup I described in previous comments (but with the latest version of main) seems like
Yes, it does look like process_response could be improved. But, at least on my computer, it feels instant to use tailwind-lsp completion now. Once again, thanks.
From my point of view, this issue could be closed.
Sweet, thanks for testing!
Can confirm that it's fixed. Thanks a lot @Saghen for taking the time to look into this :)
Sorry to be reviving this thread, I don't really understand in what version this was fixed. At least I am still experiencing this issue. The blink-cmp version in nixpkgs seems to be 1.4.1.
@Aasim-A are you adding it any differently from this to the plugins?
{
plugin = blink-cmp;
type = "lua";
config = "require('blink.cmp').setup()";
}
@Elias-Graf It'll be released in v1.5.0
@Elias-Graf Since you're using nix, if you want to use the patched version right now, you can add this to your lazy config to build from source:
build = 'nix run .#build-plugin',