From 1bd5629c5beb88077b8567e2bda86dfb71fe509d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 10:51:40 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20IconifyIcon=20lo?= =?UTF-8?q?okup=20with=20in-memory=20caching?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: sshahriazz <34005640+sshahriazz@users.noreply.github.com> --- .jules/bolt.md | 6 ++++++ client/src/components/base/IconifyIcon.tsx | 19 +++++++++++++++++-- 2 files changed, 23 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..4fcc6d1 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,6 @@ +## 2026-04-13 - [Memoize Custom IconifyIcon Component] +**Learning:** The custom `IconifyIcon` component () manually iterates over 11 imported icon sets for prefix-less icons using `getIconData` on every single render. This is extremely expensive given how often icons are rendered in the layout. +**Action:** Implemented a simple in-memory cache dictionary (`iconCache`) outside the component to store positive AND negative lookup results, reducing an (N)$ lookup to (1)$ after the first render. +## 2026-04-13 - [Memoize Custom IconifyIcon Component] +**Learning:** The custom IconifyIcon component manually iterates over 11 imported icon sets for prefix-less icons using getIconData on every single render. This is extremely expensive given how often icons are rendered in the layout. +**Action:** Implemented a simple in-memory cache dictionary (iconCache) outside the component to store positive AND negative lookup results, reducing an O(N) lookup to O(1) after the first render. diff --git a/client/src/components/base/IconifyIcon.tsx b/client/src/components/base/IconifyIcon.tsx index b48f0dc..3ce0ade 100644 --- a/client/src/components/base/IconifyIcon.tsx +++ b/client/src/components/base/IconifyIcon.tsx @@ -33,18 +33,33 @@ const iconSets: Record = { "mdi-light": mdiLightIcons, }; +// ⚡ Bolt Optimization: Cache icon data lookups to prevent redundant O(N) searches across 11 icon sets on every render. +const iconCache: Record | null> = {}; + const iconData = (icon: string) => { + if (iconCache[icon] !== undefined) return iconCache[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[icon] = data; + return data; + } } for (const [_, icons] of Object.entries(iconSets)) { const data = getIconData(icons, name); - if (data) return data; + if (data) { + iconCache[icon] = data; + return data; + } } + + // Cache negative results too so we don't repeat the loop for missing icons + iconCache[icon] = null; + return null; }; const IconifyIcon = ({