From 29a57ed12e72ce40b03b080c5fa1f7b93cd6ec05 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 11:01:45 +0000 Subject: [PATCH] feat: Cache IconifyIcon lookups Adds a module-level Map cache to `IconifyIcon.tsx` to memoize the resolution of `iconData`. This prevents performance-blocking O(N) array iteration lookups for prefix-less icons on every render. Missing items are cached as `null` to avoid redundant misses. Co-authored-by: sshahriazz <34005640+sshahriazz@users.noreply.github.com> --- .jules/bolt.md | 3 +++ client/src/components/base/IconifyIcon.tsx | 23 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..7d437c6 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-05-24 - IconifyIcon Cache Null Type Constraint +**Learning:** The custom `IconifyIcon` component requires caching negative results as `null` instead of `undefined` to satisfy Next.js build constraints for `ExtendedIconifyIcon | null`. +**Action:** Always use `null` for missing items when caching `iconData` lookups in `IconifyIcon.tsx`. diff --git a/client/src/components/base/IconifyIcon.tsx b/client/src/components/base/IconifyIcon.tsx index b48f0dc..e9808fb 100644 --- a/client/src/components/base/IconifyIcon.tsx +++ b/client/src/components/base/IconifyIcon.tsx @@ -33,18 +33,37 @@ const iconSets: Record = { "mdi-light": mdiLightIcons, }; +// ⚡ Bolt: Cache icon lookups to prevent O(N) array iteration on every render, +// especially for prefix-less or missing icons. +const iconCache = new Map>(); + const iconData = (icon: string) => { + if (iconCache.has(icon)) { + return iconCache.get(icon); + } + const [prefix, name] = icon.includes(":") ? icon.split(":") : ["", icon]; if (prefix && iconSets[prefix]) { const data = getIconData(iconSets[prefix], name); - if (data) return data; + if (data) { + iconCache.set(icon, data); + return data; + } } for (const [_, icons] of Object.entries(iconSets)) { const data = getIconData(icons, name); - if (data) return data; + if (data) { + iconCache.set(icon, data); + return data; + } } + + // ⚡ Bolt: Store missing items as `null` (not undefined) + // to satisfy the `ExtendedIconifyIcon | null` constraint in Next.js build. + iconCache.set(icon, null); + return null; }; const IconifyIcon = ({