Skip to content

Commit a35774d

Browse files
committed
perf: optimize tag frequency calculation using Obsidian's built-in cache API
1 parent eec23a4 commit a35774d

File tree

1 file changed

+19
-39
lines changed

1 file changed

+19
-39
lines changed

src/tagIndexView.ts

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,16 @@ export class TagIndexView extends ItemView {
232232
}
233233

234234
// Calculate frequencies for frequency-based sorting
235+
// Get all tag counts once from Obsidian's cache (very efficient)
235236
const frequencies = new Map<string, number>();
236237
if (method === "frequency-high" || method === "frequency-low") {
238+
const allTagCounts = (this.app.metadataCache as any).getTags();
239+
237240
tags.forEach((tag) => {
238-
const count = this.getTagFrequency(tag.name);
241+
const normalizedTagName = tag.name.startsWith("#")
242+
? tag.name
243+
: `#${tag.name}`;
244+
const count = allTagCounts[normalizedTagName] || 0;
239245
frequencies.set(tag.name, count);
240246
});
241247
}
@@ -307,44 +313,18 @@ export class TagIndexView extends ItemView {
307313
}
308314

309315
private getTagFrequency(tagName: string): number {
310-
const tagNameWithoutHash = tagName.startsWith("#")
311-
? tagName.substring(1)
312-
: tagName;
313-
314-
// Count files that contain this tag
315-
const count = this.app.vault
316-
.getMarkdownFiles()
317-
.filter((file: TFile) => {
318-
const cache = this.app.metadataCache.getFileCache(file);
319-
if (!cache) return false;
320-
321-
// Check inline tags
322-
if (cache.tags) {
323-
const hasInlineTag = cache.tags.some(
324-
(tagCache) => tagCache.tag === `#${tagNameWithoutHash}`,
325-
);
326-
if (hasInlineTag) return true;
327-
}
328-
329-
// Check frontmatter tags
330-
if (cache.frontmatter && cache.frontmatter.tags) {
331-
const frontmatterTags = cache.frontmatter.tags;
332-
if (Array.isArray(frontmatterTags)) {
333-
return frontmatterTags.some(
334-
(tag) => tag === tagNameWithoutHash,
335-
);
336-
} else if (typeof frontmatterTags === "string") {
337-
return frontmatterTags
338-
.split(",")
339-
.map((t) => t.trim())
340-
.includes(tagNameWithoutHash);
341-
}
342-
}
343-
344-
return false;
345-
}).length;
346-
347-
return count;
316+
// Use Obsidian's built-in MetadataCache API for efficient tag counting
317+
// This is much faster than manually scanning all files
318+
const allTagCounts = (this.app.metadataCache as any).getTags();
319+
320+
// Normalize tag name to ensure it has # prefix for lookup
321+
const normalizedTagName = tagName.startsWith("#")
322+
? tagName
323+
: `#${tagName}`;
324+
325+
// getTags() returns an object like: { "#tag1": 5, "#tag2": 3, ... }
326+
// where the number is how many files contain that tag
327+
return allTagCounts[normalizedTagName] || 0;
348328
}
349329

350330
private buildTree(tags?: ImportantTag[]): Map<string, TreeNode> {

0 commit comments

Comments
 (0)