From fc2b8acca90519b55b14dcca12339cbf09737a22 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 13:23:26 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20PDF=20search=20w?= =?UTF-8?q?ith=20pre-computed=20index?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 💡 What: Added `prepareSearchIndex` to pre-compute search strings and optimized `renderPDFs` to use this index and short-circuit logic. 🎯 Why: Reduces redundant `toLowerCase()` calls and skips expensive checks for filtered-out items. 📊 Impact: Faster search response and reduced CPU usage during typing. Co-authored-by: MrAlokTech <107493955+MrAlokTech@users.noreply.github.com> --- script.js | 58 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/script.js b/script.js index bdc06f3..6c08b64 100644 --- a/script.js +++ b/script.js @@ -332,6 +332,27 @@ function getAdData(slotName) { return null; } +function prepareSearchIndex() { + // 1. Create a search index for each PDF to optimize filtering + // concatenating title, description, category, and author into a single lowercased string. + // 2. We use a non-enumerable property '_searchStr' so it doesn't get serialized to localStorage + // and keeps the object clean during debugging. + pdfDatabase.forEach(pdf => { + const searchStr = [ + pdf.title, + pdf.description, + pdf.category, + pdf.author + ].map(s => (s || '').toLowerCase()).join(' '); + + Object.defineProperty(pdf, '_searchStr', { + value: searchStr, + enumerable: false, + writable: true + }); + }); +} + /* ========================================= 5. DATA LOADING WITH CACHING ========================================= */ @@ -451,6 +472,7 @@ async function loadPDFDatabase() { if (shouldUseCache) { pdfDatabase = cachedData; + prepareSearchIndex(); // Optimize search performance // --- FIX: CALL THIS TO POPULATE UI --- syncClassSwitcher(); renderSemesterTabs(); @@ -474,6 +496,8 @@ async function loadPDFDatabase() { data: pdfDatabase })); + prepareSearchIndex(); // Optimize search performance + // --- FIX: CALL THIS TO POPULATE UI --- syncClassSwitcher(); renderPDFs(); @@ -902,26 +926,30 @@ function renderPDFs() { // Locate renderPDFs() in script.js and update the filter section const filteredPdfs = pdfDatabase.filter(pdf => { - const matchesSemester = pdf.semester === currentSemester; + // 1. Check Class (Primary Filter) - Short-circuit if mismatch + if (pdf.class !== currentClass) return false; - // NEW: Check if the PDF class matches the UI's current class selection - // Note: If old documents don't have this field, they will be hidden. - const matchesClass = pdf.class === currentClass; + // 2. Check Semester - Short-circuit if mismatch + if (pdf.semester !== currentSemester) return false; - let matchesCategory = false; + // 3. Check Category - Short-circuit if mismatch if (currentCategory === 'favorites') { - matchesCategory = favorites.includes(pdf.id); - } else { - matchesCategory = currentCategory === 'all' || pdf.category === currentCategory; + if (!favorites.includes(pdf.id)) return false; + } else if (currentCategory !== 'all') { + if (pdf.category !== currentCategory) return false; } - const matchesSearch = pdf.title.toLowerCase().includes(searchTerm) || - pdf.description.toLowerCase().includes(searchTerm) || - pdf.category.toLowerCase().includes(searchTerm) || - pdf.author.toLowerCase().includes(searchTerm); - - // Update return statement to include matchesClass - return matchesSemester && matchesClass && matchesCategory && matchesSearch; + // 4. Check Search Term (Expensive Operation) + // Use the pre-computed _searchStr to avoid repeated toLowerCase() calls + if (pdf._searchStr) { + return pdf._searchStr.includes(searchTerm); + } else { + // Fallback for safety (though prepareSearchIndex ensures _searchStr exists) + return (pdf.title || '').toLowerCase().includes(searchTerm) || + (pdf.description || '').toLowerCase().includes(searchTerm) || + (pdf.category || '').toLowerCase().includes(searchTerm) || + (pdf.author || '').toLowerCase().includes(searchTerm); + } }); updatePDFCount(filteredPdfs.length);