diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..3bb5bcb --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-05-15 - [Iconify Bundle Size Optimization] +**Learning:** The application is statically importing all icon sets into `IconifyIcon.tsx` which can cause significant bundle bloat for the Next.js client. By using just string icons with `@iconify/react`, it dynamically fetches them when needed, preventing all unused icons from being included in the JS bundle. +**Action:** Remove all static imports of `@iconify-json/*` packages in `IconifyIcon.tsx` and just pass the string to the Icon component for dynamic fetching. This avoids huge amounts of unused JSON data in the bundle. diff --git a/client/src/components/base/IconifyIcon.tsx b/client/src/components/base/IconifyIcon.tsx index b48f0dc..853b0f2 100644 --- a/client/src/components/base/IconifyIcon.tsx +++ b/client/src/components/base/IconifyIcon.tsx @@ -1,16 +1,4 @@ -import { icons as entypoSocialIcons } from "@iconify-json/entypo-social"; -import { icons as evaIcons } from "@iconify-json/eva"; -import { icons as fa6Brands } from "@iconify-json/fa6-brands"; -import { icons as flagIcons } from "@iconify-json/flag"; -import { icons as icIcons } from "@iconify-json/ic"; -import { icons as materialIcons } from "@iconify-json/material-symbols"; -import { icons as materialLightIcons } from "@iconify-json/material-symbols-light"; -import { icons as mdiIcons } from "@iconify-json/mdi"; -import { icons as mdiLightIcons } from "@iconify-json/mdi-light"; -import { icons as riIcons } from "@iconify-json/ri"; -import { icons as twemojiIcons } from "@iconify-json/twemoji"; -import { Icon, IconifyJSON, IconProps } from "@iconify/react"; -import { getIconData } from "@iconify/utils"; +import { Icon, IconProps } from "@iconify/react"; import { Box, BoxProps } from "@mui/material"; interface IconifyProps extends IconProps { @@ -19,34 +7,6 @@ interface IconifyProps extends IconProps { icon: string; } -const iconSets: Record = { - "material-symbols": materialIcons, - "material-symbols-light": materialLightIcons, - twemoji: twemojiIcons, - eva: evaIcons, - ri: riIcons, - ic: icIcons, - flag: flagIcons, - "fa6-brands": fa6Brands, - "entypo-social": entypoSocialIcons, - mdi: mdiIcons, - "mdi-light": mdiLightIcons, -}; - -const iconData = (icon: string) => { - const [prefix, name] = icon.includes(":") ? icon.split(":") : ["", icon]; - - if (prefix && iconSets[prefix]) { - const data = getIconData(iconSets[prefix], name); - if (data) return data; - } - - for (const [_, icons] of Object.entries(iconSets)) { - const data = getIconData(icons, name); - if (data) return data; - } -}; - const IconifyIcon = ({ icon, flipOnRTL = false, @@ -56,7 +16,7 @@ const IconifyIcon = ({ return (