dundalek / lazy-lsp.nvim

Neovim plugin to auto install LSP servers
MIT License
194 stars 13 forks source link

Startup time optimization #34

Open dundalek opened 5 months ago

dundalek commented 5 months ago

Loading the plugin adds roughly following time penalty (measured on Linux, likely a bit slower on other OSes): 1) ~30ms loading individual lsp configs (~120ms on WSL Windows) 2) 20ms spent in lspconfig.manager afterwards

First optimization would be to reduce 2) by setting up the servers only when a file of a given filetype is opened. This would need figuring out what lspconfig does internally, which events it hooks. done in #31

Second optimization would be to reduce 1). We could build up a mapping from filetype to servers so we don't need to load individual configs upfront. The downside is that we would need to update the plugin more often to make sure it tracks the upstream to make sure we don't miss filetypes.

zoriya commented 5 months ago

Lazily loading lsp's configs could also allow extensions plugins to be loaded lazily (i'm thinking about SchemaStore for json, fluter tools, omnisharp extended for csharp and so on). Not sure how much that would change startup time tho.

fdietze commented 5 months ago

Something simple like this might have a big effect already:

local function setup_servers_for_filetype(filetype)
  local servers = filetype_to_servers[filetype] -- this mapping already exists in lazy-lsp.nvim
  if servers then
    for _, server in ipairs(servers) do
      require 'lspconfig'[server].setup {}
    end
  end
end

vim.api.nvim_create_autocmd("FileType", {
  pattern = "*",         -- This will trigger the autocommand for any filetype
  callback = function(args)
    setup_servers_for_filetype(args.match)
  end,
})

Thinking about it, the filetype_to_servers mappings and the mappings from servers to nix packages are both valuable on their own. Many different approaches could be built and tested only on those mappings. It might we worth it to extract those mappings into their own plugins at some point.

For example: On any open file, have a command to show a selection of available servers, which can be installed using nix-env or nix profile (for nixos with flakes).

dundalek commented 5 months ago

local servers = filetype_to_servers[filetype] -- this mapping already exists in lazy-lsp.nvim

This mapping is collected during start by reading all lspconfig files which ends up loading around 100 files. Optimization (1.) is about precomputing the mapping and shipping it as part of the plugin, which would result in loading only one file and should drop the time to be within single digit milliseconds.

Registering autocmd based on corresponding filetypes to run setups lazily (2.) is now implemented.