@@ -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