Skip to content

Commit cc8c1ac

Browse files
wmohammed-congaWaseem
andauthored
perf(website): cache normalized search fields (#4245)
Precompute lowercased search fields once per index identity so each query avoids repeating normalization across every indexed item.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Co-authored-by: Waseem <wmohammed@pros.com>
1 parent 0c54bce commit cc8c1ac

1 file changed

Lines changed: 26 additions & 7 deletions

File tree

‎website/src/components/brand/TopNavSearch.tsx‎

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ const MAX_PER_GROUP = 4;
2929
const MAX_PAGEFIND_HITS = 12;
3030

3131
type ResultGroup = { category: SearchCategory; items: SearchItem[] };
32+
type NormalizedSearchItem = {
33+
item: SearchItem;
34+
title: string;
35+
description: string;
36+
category: string;
37+
};
3238

3339
/**
3440
* Shared top-navigation search. A collapsed magnifier button expands into a
@@ -120,15 +126,28 @@ export function TopNavSearch({
120126
};
121127
}, [trimmed]);
122128

129+
const normalizedIndex = useMemo<NormalizedSearchItem[]>(
130+
() =>
131+
index.map((item) => ({
132+
item,
133+
title: item.title.toLowerCase(),
134+
description: item.description.toLowerCase(),
135+
category: item.category.toLowerCase(),
136+
})),
137+
[index],
138+
);
139+
123140
const groups = useMemo<ResultGroup[]>(() => {
124141
const query = trimmed.toLowerCase();
125142
if (query.length === 0) return [];
126-
const staticMatches = index.filter(
127-
(item) =>
128-
item.title.toLowerCase().includes(query) ||
129-
item.description.toLowerCase().includes(query) ||
130-
item.category.toLowerCase().includes(query),
131-
);
143+
const staticMatches = normalizedIndex
144+
.filter(
145+
({ title, description, category }) =>
146+
title.includes(query) ||
147+
description.includes(query) ||
148+
category.includes(query),
149+
)
150+
.map(({ item }) => item);
132151
// Static hits win on ties: they carry curated titles and descriptions.
133152
const seen = new Set(staticMatches.map((item) => hrefKey(item.href)));
134153
const matches = [...staticMatches];
@@ -150,7 +169,7 @@ export function TopNavSearch({
150169
grouped.push({ category, items });
151170
}
152171
return grouped;
153-
}, [trimmed, index, pagefindHits]);
172+
}, [trimmed, normalizedIndex, pagefindHits]);
154173

155174
const flatResults = useMemo(
156175
() => groups.flatMap((group) => group.items),

0 commit comments

Comments
 (0)