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 performance issues #1828

Open
2 tasks done
mortezadadgar opened this issue Feb 17, 2024 · 11 comments
Open
2 tasks done

TailwindCSS performance issues #1828

mortezadadgar opened this issue Feb 17, 2024 · 11 comments
Labels
bug Something isn't working

Comments

@mortezadadgar
Copy link

FAQ

  • I have checked the FAQ and it didn't resolve my problem.

Announcement

Minimal reproducible full config

if has('vim_starting')
  set encoding=utf-8
endif
scriptencoding utf-8

if &compatible
  set nocompatible
endif

let s:plug_dir = expand('/tmp/plugged/vim-plug')
if !filereadable(s:plug_dir .. '/plug.vim')
  execute printf('!curl -fLo %s/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim', s:plug_dir)
end

execute 'set runtimepath+=' . s:plug_dir
call plug#begin(s:plug_dir)
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/vim-vsnip'
Plug 'neovim/nvim-lspconfig'
call plug#end()
PlugInstall | quit

" Setup global configuration. More on configuration below.
lua << EOF
local cmp = require "cmp"
cmp.setup {
  snippet = {
    expand = function(args)
      vim.fn["vsnip#anonymous"](args.body)
    end,
  },

  mapping = {
    ['<CR>'] = cmp.mapping.confirm({ select = true })
  },

  sources = cmp.config.sources({
    { name = "nvim_lsp" },
    { name = "buffer" },
  }),
}
EOF

lua << EOF
local capabilities = require('cmp_nvim_lsp').default_capabilities()

require'lspconfig'.tailwindcss.setup {
  capabilities = capabilities,
}
EOF

Description

I know #1583 and #1574 has improved the performance of tailwindcss completions but I think performance still is not on pair with programs such as vscode.

the issue is apparent after inserting a new space after the bg-white class in recorded video
https://github.com/hrsh7th/nvim-cmp/assets/27911493/5aca7637-f5c6-4264-9bfb-99d9ee1008d6

recorded another video to better illustrate it
https://github.com/hrsh7th/nvim-cmp/assets/27911493/5492540e-901a-43cf-9e27-0c0688443fc2

Steps to reproduce

initialize tailwindcss in any web development project and type in a html tag class.

Expected behavior

to be butter smooth.

Actual behavior

described in description section.

Additional context

No response

@mortezadadgar mortezadadgar added the bug Something isn't working label Feb 17, 2024
@dan-cooke
Copy link

dan-cooke commented Mar 6, 2024

Yep I am still experiencing major lag with tailwind LSP installed, I have resorted to removing it.
LSP zero config

local lsp = require('lsp-zero').preset({
})

local lspconfig = require('lspconfig')


lsp.ensure_installed({
	'tsserver',
	'eslint',
	'rust_analyzer',
})


lsp.on_attach(function(client, bufnr)
	local capabilities = vim.lsp.protocol.make_client_capabilities()
	capabilities.textDocument.completion.completionItem.snippetSupport = true
	lsp.default_keymaps({ buffer = bufnr })
	lsp.buffer_autoformat()
end)

vim.keymap.set("n", "gr", ":lua vim.lsp.buf.rename() <cr> :wall <cr>")
vim.keymap.set("n", "<leader>g", ":lua vim.lsp.buf.hover() <cr>")
vim.keymap.set("n", "<leader>]", ":lua vim.diagnostic.goto_next() <cr>")
vim.keymap.set("n", "<leader>[", ":lua vim.diagnostic.goto_prev() <cr>")
vim.keymap.set("n", "gh", ":lua vim.diagnostic.open_float() <cr>")
vim.keymap.set("n", "gd", ":lua vim.lsp.buf.definition() <cr>")
vim.diagnostic.config({
	virtual_text = false,
	root_dir = require("lspconfig.util").root_pattern(".git")
})

lsp.format_on_save({
	format_opts = {
		async = false,
		timeout_ms = 10000,
	},
	servers = {
		['rust_analyzer'] = { 'rust' },
		['prettier'] = { 'css', 'html', 'javascript', 'javascriptreact', 'json', 'less', 'scss', 'typescript', 'typescriptreact', 'vue' },
	}
})




lsp.set_server_config({
	on_init = function(client)
		client.server_capabilities.semanticTokensProvider = nil
	end,
})

lsp.set_sign_icons({
	error = '',
	warn = '',
	hint = '',
	info = '»'
})


lspconfig.tsserver.setup({
	root_dir = require("lspconfig.util").root_pattern(".git"),
	flags = {
		allow_incremental_sync = false,
		debounce_text_changes = 500,
	},
})


lsp.setup()

nvim-cmp config

local cmp = require('cmp')
local lspkind = require('lspkind')

cmp.setup({
	mapping = {
		['<CR>'] = cmp.mapping.confirm({ select = false }),
		['<C-c>'] = cmp.mapping.complete(),
		['<C-e>'] = cmp.mapping(function(fallback)
			if cmp.visible() then
				cmp.abort()
			else
				fallback()
			end
		end, { 'i', 'c' }),
		["<Tab>"] = cmp.mapping(function(fallback)
			if cmp.visible() then
				cmp.select_next_item({ behavior = cmp.SelectBehavior.Select })
			else
				fallback()
			end
		end),
		['<S-Tab>'] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }),
	},

	formatting = {
		format = lspkind.cmp_format({
			mode = "symbol_text",
			max_width = 50,
			symbol_map = { Copilot = "" }
		})
	},



	experimental = {
		ghost_text = true,
	},


	snippet = {
		-- REQUIRED - you must specify a snippet engine
		expand = function(args)
			require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
			-- require('snippy').expand_snippet(args.body) -- For `snippy` users.
			-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
		end,
	},


	sources = {
		-- Other Sources
		-- { name = "copilot",  group_index = 2 },
		{ name = "nvim_lsp", group_index = 2, keyword_length = 6 },
		{ name = "path",     group_index = 2 },
		{ name = "luasnip",  group_index = 2 },
	},
})

Ram usage has got has high as 99% with tailwind LSP enabled, without it im always sitting around 30% with Firefox open

@Shougo
Copy link

Shougo commented Mar 6, 2024

Hm.... But this is tailscale LS problem.

@mortezadadgar
Copy link
Author

mortezadadgar commented Mar 6, 2024

@Shougo but mini.completion and vscode doesn't suffer from this issue

@Shougo
Copy link

Shougo commented Mar 7, 2024

I think mini.completion does not use fuzzy match.
If the items are very big from LS, nvim-cmp fuzzy match is very slow.

@Shougo
Copy link

Shougo commented Mar 7, 2024

I have tested it. Hm. It seems slow.

Its slowness is from:

  • The auto completion keyword length is 0(The items are very huge)

  • If items are huge, the filtering is very slow(Because it is fuzzy match)

@Shougo
Copy link

Shougo commented Mar 7, 2024

@Shougo
Copy link

Shougo commented Mar 7, 2024

It is better for me.

" Setup global configuration. More on configuration below.
lua << EOF
local cmp = require "cmp"
cmp.setup {
  snippet = {
    expand = function(args)
      vim.fn["vsnip#anonymous"](args.body)
    end,
  },

  mapping = {
    ['<CR>'] = cmp.mapping.confirm({ select = true })
  },

  matching = {
    disallow_partial_matching = true,
    disallow_fuzzy_matching = true,
    disallow_prefix_unmatching = true,
  },

  sources = cmp.config.sources({
    { name = "nvim_lsp", keyword_length = 2 },
    { name = "buffer" },
  }),
}
EOF

lua << EOF
local capabilities = require('cmp_nvim_lsp').default_capabilities()

require'lspconfig'.tailwindcss.setup {
  capabilities = capabilities,
}
EOF

@dan-cooke
Copy link

@Shougo i will try disabling these settings and get back to you, my keyword length was 6 though and still very slow

@dan-cooke
Copy link

@Shougo yeah that's faster but now it just a really subpar experience in my opinion.

@Shougo
Copy link

Shougo commented Mar 8, 2024

source.complete = function(self, params, callback)
  local lsp_params = vim.lsp.util.make_position_params(0, self.client.offset_encoding)
  lsp_params.context = {}
  lsp_params.context.triggerKind = params.completion_context.triggerKind
  lsp_params.context.triggerCharacter = params.completion_context.triggerCharacter
  self:_request('textDocument/completion', lsp_params, function(_, response)
    vim.print(response)
    callback(response)
  end)
end

I have checked response.
The response is not filtered by LS and the size is very huge.

    }, {
      kind = 21,
      label = "forced-color-adjust-none",
      sortText = "11282"
    } }

11282 items are returned. It is slow for Lua.

@mortezadadgar
Copy link
Author

yeah nvim-cmp to filter and sort all those responses primary reason is that tailwindcss triggers completion on spaces which send the maximum number of completion items; removing space from triggerCharacters can significantly improves performance

vim.api.nvim_create_autocmd("LspAttach", {
	group = vim.api.nvim_create_augroup("UserLspConfig", {}),
	callback = function(ev)
		for _, client in pairs((vim.lsp.get_clients {})) do
			if client.name == "tailwindcss" then
				client.server_capabilities.completionProvider.triggerCharacters =
					{ '"', "'", "`", ".", "(", "[", "!", "/", ":" }
			end
		end
	end,
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants