Agent Skills: Lazy.nvim Optimization

>-

UncategorizedID: kriscard/kriscard-claude-plugins/lazy-nvim-optimization

Install this agent skill to your local

pnpm dlx add-skill https://github.com/kriscard/kriscard-claude-plugins/tree/HEAD/plugins/neovim-advisor/skills/lazy-nvim-optimization

Skill Files

Browse the full folder contents for lazy-nvim-optimization.

Download Skill

Loading file tree…

plugins/neovim-advisor/skills/lazy-nvim-optimization/SKILL.md

Skill Metadata

Name
lazy-nvim-optimization
Description
>-

Lazy.nvim Optimization

Diagnose and fix Neovim startup performance through profiling and targeted lazy-loading.

Profiling Workflow

When a user reports slow startup, follow this sequence — don't skip to solutions.

Step 1: Measure Baseline

nvim --startuptime startup.log && tail -1 startup.log

Compare against targets:

  • < 30ms: Excellent
  • 30-50ms: Good
  • 50-100ms: Acceptable
  • 100ms: Needs work

Step 2: Identify Slow Plugins

:Lazy profile

Look for plugins with load time > 10ms. These are your optimization targets. Sort by time, not alphabetically.

Also check the startup log for:

  • Files taking > 10ms to source
  • setup() functions taking > 5ms
  • Synchronous operations blocking startup

Step 3: Apply Lazy-Loading

For each slow plugin, choose the right trigger:

| Plugin Type | Trigger | Example | |-------------|---------|---------| | Has clear commands | cmd | cmd = "Telescope" | | Accessed via keybindings | keys | keys = { "<leader>e" } | | Language-specific | ft | ft = { "rust", "go" } | | Needed after UI renders | event = "VeryLazy" | UI enhancements | | Needed when editing | event = "BufReadPost" | Git signs, diagnostics | | Needed in insert mode | event = "InsertEnter" | Completion, autopairs | | Only used as dependency | lazy = true | plenary.nvim |

Step 4: Verify Improvement

nvim --startuptime startup-after.log && tail -1 startup-after.log

Compare total times. Then :Lazy profile to verify plugins load when expected.

What NOT to Lazy-Load

These need to load at startup — don't fight it:

  • Colorscheme — Set priority = 1000 so it loads first. Visible flash if deferred.
  • Treesitter — Needed for syntax highlighting immediately. Deferring causes flicker.
  • Statusline — Visible at startup. Deferring causes layout shift.
  • which-key — Only if it shows on startup. Otherwise can lazy-load.
  • LSP base setup — Though individual servers can lazy-load by filetype.

Common Bottlenecks

Synchronous system calls at startup:

-- Bad: blocks startup
vim.fn.system("git status")

-- Good: defer it
vim.defer_fn(function()
  vim.fn.system("git status")
end, 100)

Loading all LSP servers at once: Consider loading LSP servers per-filetype instead of all at startup. Each server you don't load saves 5-15ms.

Plugins without any trigger: A bare { "plugin/name" } spec loads at startup. Always add a trigger unless the plugin genuinely needs immediate availability.

Performance Checklist

Startup

  • [ ] Colorscheme has priority = 1000
  • [ ] File explorers load on cmd/keys
  • [ ] Git interfaces load on cmd/keys
  • [ ] Completion loads on InsertEnter
  • [ ] Language plugins load on filetype
  • [ ] UI enhancements load on VeryLazy

Runtime

  • [ ] Telescope uses fzf-native extension
  • [ ] Treesitter parsers installed only for used languages
  • [ ] LSP servers only for filetypes you use
  • [ ] No plugins duplicating built-in 0.10+ features

Config

  • [ ] No synchronous system calls at startup
  • [ ] setup() only runs when plugins load
  • [ ] Keymaps defined with plugin lazy-loading
  • [ ] Auto-commands use specific events, not "*"

Reference Files

For detailed information:

  • references/lazy-loading-decision-tree.md - Decision tree for choosing lazy-loading strategy
  • references/profiling-guide.md - Advanced profiling techniques