Skip to content

Comments

fix: defer heavy module loading for faster startup (#272)#275

Merged
esmuellert merged 2 commits intomainfrom
dev
Feb 24, 2026
Merged

fix: defer heavy module loading for faster startup (#272)#275
esmuellert merged 2 commits intomainfrom
dev

Conversation

@esmuellert
Copy link
Owner

Summary

Reduces codediff.nvim's startup impact from ~15ms to ~0.6ms (96% reduction) by deferring heavy module loading until the user first invokes :CodeDiff.

Closes #272

Problem

plugin/codediff.lua eagerly loaded 42 Lua modules + a C library via FFI at startup, even when the user never used any diff functionality. This consumed ~15ms on cold start and ~8ms on warm start.

Before (startup profiling)

       startup: 48.9

codediff.lua            19.42   39.75 ███████████▊
codediff.ui             18.75   38.38 ███████████▌
codediff.ui.view        18.38   37.62 ███████████▎
codediff.ui.explorer     2.12    4.33 █▎
codediff.ui.auto_refresh 1.75    3.57 █
codediff.core.diff       1.09    2.24 ▌

After

       startup: 7.3

codediff.lua             0.58    7.92 ██▎
codediff.ui.highlights   0.31    4.32 █▎
codediff.config          0.18    2.47 ▌
codediff.core.virtual_file 0.09  1.20 ▎

Changes

  • plugin/codediff.lua: Replace 4 eager top-level require() calls with 2 lightweight ones (codediff.ui.highlights + codediff.core.virtual_file). Wrap the :CodeDiff command handler to lazy-load codediff.commands on first invocation.
  • plugin/vscode-diff.lua: Lazy-wrap the :VscodeDiff command handler.
  • lua/codediff/ui/init.lua: Remove eager lifecycle.setup() call (was registering global autocmds at startup).
  • lua/codediff/ui/view/init.lua: Add once-guard to call lifecycle.setup() on first view.create(), so cleanup autocmds are only registered when actually needed.

What loads at startup (~0.6ms)

  • codediff.ui.highlights — highlight group definitions
  • codediff.core.virtual_filecodediff:// URL scheme registration
  • Command registration (negligible)

What's deferred to first :CodeDiff invocation

  • C diff library (FFI + ffi.load())
  • Explorer, History, Conflict UI modules
  • Lifecycle autocmds (WinClosed/TabClosed/BufEnter)
  • Git operations module
  • View keymaps, navigation, layout

Testing

  • ✅ All plenary tests pass (37 files, 0 failures)
  • ✅ E2E validation: :CodeDiff file, :VscodeDiff, lifecycle cleanup, multi-tab all work
  • ✅ 5 profiling runs confirm consistent ~0.6ms startup

esmuellert and others added 2 commits February 24, 2026 00:34
Reduce startup impact from ~15ms to ~0.6ms by deferring heavy requires
(UI, diff engine, explorer, history, lifecycle) until first :CodeDiff
invocation. Only highlights and virtual_file scheme load at startup.

- plugin/codediff.lua: replace 4 eager requires with 2 lightweight ones;
  wrap command handler to lazy-load codediff.commands
- plugin/vscode-diff.lua: lazy-wrap command handler
- lua/codediff/ui/init.lua: remove eager lifecycle.setup() call
- lua/codediff/ui/view/init.lua: add once-guard to call lifecycle.setup()
  on first view.create()

Closes #272

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@esmuellert esmuellert enabled auto-merge February 24, 2026 05:34
@esmuellert esmuellert merged commit 783258e into main Feb 24, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lazy loading

1 participant