@@ -83,51 +83,59 @@ let preloadedFrontMatter: Record<string, any>[] | null = null;
8383// Preload frontmatter from JSON file (optimized approach)
8484export async function preloadFrontmatter ( ) {
8585 if ( preloadedFrontMatter ) return ; // Already loaded
86-
86+
8787 try {
8888 const response = await fetch ( '/frontmatter.json' ) ;
8989 if ( response . ok ) {
9090 preloadedFrontMatter = await response . json ( ) ;
9191 if ( preloadedFrontMatter ) {
9292 completeFrontMatter = [ ...preloadedFrontMatter ] ;
93-
93+
9494 // Update navigation titles from preloaded data
9595 for ( const fm of preloadedFrontMatter ) {
9696 updateNavigationTitle ( fm . path , fm . title ) ;
9797 }
98-
99- // Add to search index
100- await addPreloadedContentToSearch ( ) ;
98+
99+ // Build search index in the background — don't block page rendering.
100+ // Each page's raw MDX is fetched individually, so for large sites this
101+ // can be hundreds of requests. We batch them to avoid overwhelming the
102+ // browser's connection pool.
103+ addPreloadedContentToSearch ( ) ;
101104 }
102105 }
103106 } catch ( error ) {
104107 console . warn ( 'Failed to load prebuilt frontmatter JSON, falling back to dynamic loading:' , error ) ;
105108 }
106109}
107110
108- // Add preloaded content to search index
111+ // Add preloaded content to search index (runs in background, never blocks rendering)
109112async function addPreloadedContentToSearch ( ) {
110113 if ( ! preloadedFrontMatter ) return ;
111-
114+
112115 const mdxFiles = import . meta. glob < { default : string } > ( '../../docs/**/*.mdx' , { query : '?raw' } ) ;
113116 const fileEntries = Object . entries ( mdxFiles ) ;
114117
115- await Promise . all (
116- preloadedFrontMatter . map ( async ( fm ) => {
117- const fileEntry = fileEntries . find ( ( [ filePath ] ) => pathFromFilename ( filePath ) === fm . path ) ;
118- if ( fileEntry ) {
119- try {
120- const [ , loader ] = fileEntry ;
121- const rawContent = ( await loader ( ) ) . default ;
122- const { content } = parseFrontMatter ( rawContent ) ;
123-
124- await addToSearchIndex ( fm . path , { title : fm . title } , content ) ;
125- } catch ( error ) {
126- console . warn ( `Failed to index ${ fm . path } :` , error ) ;
118+ // Index in batches to avoid firing hundreds of requests at once
119+ const BATCH_SIZE = 10 ;
120+ for ( let i = 0 ; i < preloadedFrontMatter . length ; i += BATCH_SIZE ) {
121+ const batch = preloadedFrontMatter . slice ( i , i + BATCH_SIZE ) ;
122+ await Promise . all (
123+ batch . map ( async ( fm ) => {
124+ const fileEntry = fileEntries . find ( ( [ filePath ] ) => pathFromFilename ( filePath ) === fm . path ) ;
125+ if ( fileEntry ) {
126+ try {
127+ const [ , loader ] = fileEntry ;
128+ const rawContent = ( await loader ( ) ) . default ;
129+ const { content } = parseFrontMatter ( rawContent ) ;
130+
131+ await addToSearchIndex ( fm . path , { title : fm . title } , content ) ;
132+ } catch ( error ) {
133+ console . warn ( `Failed to index ${ fm . path } :` , error ) ;
134+ }
127135 }
128- }
129- } )
130- ) ;
136+ } )
137+ ) ;
138+ }
131139}
132140
133141// Load frontmatter for a specific pathname (optimized with fallback)
0 commit comments