From 2efadcf2223f652c8c507a7c94ca18839b64a0a1 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 11:08:02 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20IconifyIcon=20pr?= =?UTF-8?q?efixless=20lookups=20with=20memoization?= 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 | 3 +++ client/src/components/base/IconifyIcon.tsx | 27 ++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..c0dfa88 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-04-27 - Cache Prefixless IconifyIcon Lookups +**Learning:** Prefixless icon lookups in `IconifyIcon` invoke an `Object.entries(iconSets)` loop and multiple string parses per icon render, causing an O(N) lookup bottleneck when rendering many icons. +**Action:** Always wrap frequent, pure, synchronous lookup functions (like icon resolving) in a global memoization cache map to make them O(1), significantly reducing CPU overhead during heavy UI rendering. diff --git a/client/src/components/base/IconifyIcon.tsx b/client/src/components/base/IconifyIcon.tsx index b48f0dc..d9f56b7 100644 --- a/client/src/components/base/IconifyIcon.tsx +++ b/client/src/components/base/IconifyIcon.tsx @@ -33,18 +33,35 @@ const iconSets: Record = { "mdi-light": mdiLightIcons, }; +// ⚡ Bolt: Cache icon lookups to avoid O(N) loop on every render +const iconCache = new Map(); + const iconData = (icon: string) => { + if (iconCache.has(icon)) return iconCache.get(icon); + const [prefix, name] = icon.includes(":") ? icon.split(":") : ["", icon]; + let foundData = undefined; + if (prefix && iconSets[prefix]) { - const data = getIconData(iconSets[prefix], name); - if (data) return data; + foundData = getIconData(iconSets[prefix], name); } - for (const [_, icons] of Object.entries(iconSets)) { - const data = getIconData(icons, name); - if (data) return data; + if (!foundData) { + for (const [_, icons] of Object.entries(iconSets)) { + const data = getIconData(icons, name); + if (data) { + foundData = data; + break; + } + } } + + if (foundData) { + iconCache.set(icon, foundData); + } + + return foundData; }; const IconifyIcon = ({