-
-
Notifications
You must be signed in to change notification settings - Fork 171
perf: progressive file loading for non-blocking startup #1073
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
base: master
Are you sure you want to change the base?
Conversation
b98721c to
6953f29
Compare
|
Thanks for the PR! A lot of things are going on here. I did a quick overview of the PR, but didn't go into the details. I'd like to avoid adding all of this if possible. diff --git a/lua/orgmode/files/init.lua b/lua/orgmode/files/init.lua
index 93dad13..29d129a 100644
--- a/lua/orgmode/files/init.lua
+++ b/lua/orgmode/files/init.lua
@@ -70,7 +70,7 @@ function OrgFiles:load(force)
end
return orgfile
end)
- end, self:_files(true), 50):next(function()
+ end, self:_files(true), 30):next(function()
self.load_state = 'loaded'
return self
end)
diff --git a/lua/orgmode/utils/promise.lua b/lua/orgmode/utils/promise.lua
index 06227b7..a3d384b 100644
--- a/lua/orgmode/utils/promise.lua
+++ b/lua/orgmode/utils/promise.lua
@@ -366,7 +366,9 @@ function Promise.map(callback, list, concurrency)
:next(function(...)
results[i] = ...
processing = processing - 1
- processNext()
+ vim.defer_fn(function()
+ processNext()
+ end, 1)
end)
:catch(function(...)
reject(...)
You can tweak the number in |
Add progressive file loading with configurable ordering and per-file callbacks for incremental UI updates: - load_progressive(opts) loads files in smart order (mtime/name/custom) - on_file_loaded callback per file with index/total for progress - on_complete callback when all files loaded - current_buffer_first prioritizes active buffer (default: true) - filter option for pre-load filtering - get_load_progress() returns current loading state Enables consumers like telescope-orgmode to show results incrementally as files load, improving perceived performance for large file collections.
Expose progressive loading capabilities through public Org API: - scan_files() for fast metadata retrieval - load_files() for progressive loading with callbacks - on_file_loaded/on_files_loaded() for event registration - is_files_loaded/get_files_progress() for state tracking Adds org_async_loading config option (default: false).
Enhanced the progressive loading profiler to show batch-level metrics: - Wall Time: cumulative time since load start - Duration: how long each batch took to process - Yield Gap: time between batches (during vim.defer_fn yield) - Size: total file size per batch - Mem Δ: Lua memory delta (shows GC activity) Added diagnostic options: - first_batch_size: use smaller first batch to measure init overhead - yield_ms: configurable yield timeout (default 1ms) This helps diagnose performance issues by showing where time is spent during progressive file loading.
Introduce smart batching: - load the opened buffers in the first batch - by default load the rest in one second batch - expose API, where caller can set batch sizes Opened buffers are loaded always first, prioritizing them seems to be almost always the desired behavior.
Replace inline profiling in init.lua with a standalone profiler module that observes events. Main code now emits lightweight profiling events via emit.profile() instead of calling profiler methods directly. Key changes: - Add lua/orgmode/utils/profiler.lua with display and plugin API - Add profiling event type and emit helper - Remove ~200 lines of profiler code from init.lua and clock - Add profiling.enabled config option (default: false) - Add unit tests for payload passthrough, timing, and event ordering The event-based design means: - Zero overhead when profiling disabled (no listener registered) - Main code has no profiler imports - Plugins can profile their own code via Profiler.create_session()
Replace blocking clock search with time-boxed async batches. Uses 50ms budget per batch to keep UI responsive during navigation.
2d7f88b to
72ff28e
Compare
Summary
This PR introduces progressive file loading to eliminate startup blocking on large org directories. Instead of parsing all files synchronously (which could freeze the editor for multiple seconds with larger orgfile collections), files now load in batches with yields between them, keeping the UI responsive.
Motivation
As a tmux user who frequently opens and closes Neovim instances, and with a large collection of org files, startup blocking was a constant friction point. As the maintainer of telescope-orgmode.nvim, I also needed a public API that enables progressive file loading - allowing plugins to show immediate results to users, even on first startup. The goal is a smooth, non-blocking experience throughout.
This PR focuses on the core loading infrastructure. Follow-up PRs for progressive agenda loading may come later.
Key improvements
Related Issues
Changes
OrgFiles:scan()for fast file metadata retrieval without parsingOrgFiles:load_progressive()with batching, yielding, and callbacksOrgFiles:request_load()as unified, idempotent loading entry pointOrgFiles:get_clocked_headline_async()for non-blocking clock searchscan_files()load_files()on_file_loaded()on_files_loaded()is_files_loaded()get_files_progress():Org profilingcommand for performance debuggingChecklist
I confirm that I have:
Conventional Commits
specification (e.g.,
feat: add new feature,fix: correct bug,docs: update documentation).make test.