perf(obsidian): optimize folder tree for large vaults

The previous implementation read ALL file contents to get frontmatter
when browsing notes, which caused massive slowdown for large vaults
(13k+ files = 13k+ HTTP requests).

Changes:
- Add listAllNotePaths() function that only gets file paths (fast)
- Build folder tree from paths only, no content reading
- Lazy load file content only when user clicks on a file
- Change message from "Loading all notes" to "Loading file list"
- Add logging to show file count being displayed

Performance improvement:
- Before: O(n) HTTP requests where n = number of files
- After: O(1) - just the recursive directory scan
- File content loaded on-demand (1 request per clicked file)

This makes the folder tree instant even for vaults with 10k+ files.
This commit is contained in:
Claude 2025-11-14 05:18:07 +00:00
parent 996b653421
commit 91bd678535
No known key found for this signature in database
2 changed files with 31 additions and 5 deletions

View file

@ -300,16 +300,19 @@ async function promptCreateNewNote(elementId, elementType, coordinates) {
};
const showBrowse = async () => {
resultsDiv.innerHTML = "<p>Loading all notes...</p>";
resultsDiv.innerHTML = "<p>Loading file list...</p>";
try {
const allNotes = await ObsidianBridge.listAllNotes();
// Use fast path-only listing (doesn't read file contents)
const allNotes = await ObsidianBridge.listAllNotePaths();
if (allNotes.length === 0) {
resultsDiv.innerHTML = "<p style='color: #999;'>No notes in vault</p>";
return;
}
INFO && console.log(`Displaying ${allNotes.length} notes in folder tree`);
// Build folder tree
const tree = buildFolderTree(allNotes);
resultsDiv.innerHTML = renderFolderTree(tree, allNotes);
@ -321,12 +324,15 @@ async function promptCreateNewNote(elementId, elementType, coordinates) {
$("#alert").dialog("close");
try {
const note = allNotes[index];
// Read the file content only when clicked
const content = await ObsidianBridge.getNote(note.path);
const {frontmatter} = ObsidianBridge.parseFrontmatter(content);
resolve({
path: note.path,
name: note.name,
content,
frontmatter: note.frontmatter
frontmatter
});
} catch (error) {
reject(error);