Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

## 2024-05-25 - Iconify Object Lookup Memoization
**Learning:** In the client application, the `IconifyIcon` wrapper component dynamically searches through massive JSON objects (`@iconify-json/*`) inside `getIconData()` for every rendered icon if caching is not implemented. Because the app uses icons heavily in layouts and UI components, omitting an upfront string-to-data cache causes repeated $O(N)$ lookup costs over thousands of keys that synchronously block the main thread.
**Action:** Always verify that high-frequency UI components, especially those decoding layout icons from massive dictionaries, memoize their lookup results using an $O(1)$ structure (like a `Map`) to prevent severe cascading render delays.
25 changes: 20 additions & 5 deletions client/src/components/base/IconifyIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,33 @@ const iconSets: Record<string, IconifyJSON> = {
"mdi-light": mdiLightIcons,
};

const iconCache = new Map<string, any>();

const iconData = (icon: string) => {
if (iconCache.has(icon)) {
return iconCache.get(icon);
}

const [prefix, name] = icon.includes(":") ? icon.split(":") : ["", icon];

let data;
if (prefix && iconSets[prefix]) {
const data = getIconData(iconSets[prefix], name);
if (data) return data;
data = getIconData(iconSets[prefix], name);
}

for (const [_, icons] of Object.entries(iconSets)) {
const data = getIconData(icons, name);
if (data) return data;
if (!data) {
for (const [_, icons] of Object.entries(iconSets)) {
const foundData = getIconData(icons, name);
if (foundData) {
data = foundData;
break;
}
}
}

iconCache.set(icon, data);

return data;
};

const IconifyIcon = ({
Expand Down