[{"data":1,"prerenderedAt":10},["ShallowReactive",2],{"guide-optimize-svg-icons-for-performance":3},{"slug":4,"title":5,"description":6,"date":7,"order":8,"html":9},"optimize-svg-icons-for-performance","Optimizing SVG icons for web performance","How to keep icons from slowing your site down — minifying SVGs, choosing between inline, sprite and external files, caching, and loading large icon sets efficiently.","2026-09-23",9,"\u003Cp>A single icon is tiny, usually well under a kilobyte. But icons add up. A page with 60 inline icons, or a bundle that accidentally includes a whole icon library, can add hundreds of kilobytes. Here&#39;s how to keep icons fast.\u003C\u002Fp>\n\u003Ch2>1. Start with clean SVGs\u003C\u002Fh2>\n\u003Cp>Icons exported from design tools often carry editor metadata, unnecessary groups, IDs and overly precise numbers. Fluent UI System Icons are already clean: typically just an \u003Ccode>&lt;svg&gt;\u003C\u002Fcode> with one or two \u003Ccode>&lt;path&gt;\u003C\u002Fcode> elements. If you draw or modify your own icons, run them through \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fsvg\u002Fsvgo\">SVGO\u003C\u002Fa>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">npx svgo -f .\u002Ficons -o .\u002Ficons-optimized\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>SVGO strips metadata, merges paths and rounds coordinates, often cutting file size by 30–60% for design-tool exports.\u003C\u002Fp>\n\u003Ch2>2. Only ship the icons you use\u003C\u002Fh2>\n\u003Cp>This is the biggest win, and the easiest to get wrong.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>With \u003Ccode>@fluentui\u002Freact-icons\u003C\u002Fcode>\u003C\u002Fstrong>, import icons by name (\u003Ccode>import { Delete24Regular } from &quot;@fluentui\u002Freact-icons&quot;\u003C\u002Fcode>). Modern bundlers keep only those icons.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Avoid\u003C\u002Fstrong> building dynamic lookups like \u003Ccode>icons[name]\u003C\u002Fcode> from the whole package. They force the bundler to include everything.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>With Iconify and unplugin-icons\u003C\u002Fstrong>, each import compiles to just that icon.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Check your production bundle with a visualizer (such as \u003Ccode>rollup-plugin-visualizer\u003C\u002Fcode> or Next.js&#39;s bundle analyzer) at least once. It&#39;s the fastest way to catch a whole icon library sneaking in.\u003C\u002Fp>\n\u003Ch2>3. Pick the right delivery method\u003C\u002Fh2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Method\u003C\u002Fth>\n\u003Cth>Extra requests\u003C\u002Fth>\n\u003Cth>Cacheable\u003C\u002Fth>\n\u003Cth>Recolor with CSS\u003C\u002Fth>\n\u003Cth>Good for\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>Inline SVG\u003C\u002Ftd>\n\u003Ctd>None\u003C\u002Ftd>\n\u003Ctd>With the page\u003C\u002Ftd>\n\u003Ctd>Yes\u003C\u002Ftd>\n\u003Ctd>A handful of UI icons\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>SVG sprite (\u003Ccode>&lt;use href&gt;\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd>One\u003C\u002Ftd>\n\u003Ctd>Yes\u003C\u002Ftd>\n\u003Ctd>Yes\u003C\u002Ftd>\n\u003Ctd>Many repeated icons on multi-page sites\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>External file (\u003Ccode>&lt;img&gt;\u003C\u002Fcode>, CSS)\u003C\u002Ftd>\n\u003Ctd>One per icon\u003C\u002Ftd>\n\u003Ctd>Yes\u003C\u002Ftd>\n\u003Ctd>Only with CSS masks\u003C\u002Ftd>\n\u003Ctd>Large grids, content images\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch3>Inline SVG\u003C\u002Fh3>\n\u003Cp>Inline is fastest for the first render of a few icons: no extra requests, and no flash of missing icons. Repeating the same 800-byte path 50 times in a list isn&#39;t, though. Compression helps, but the browser still has to parse all of it.\u003C\u002Fp>\n\u003Ch3>SVG sprites\u003C\u002Fh3>\n\u003Cp>A sprite bundles many icons into one file as \u003Ccode>&lt;symbol&gt;\u003C\u002Fcode> elements. You reference them by ID:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-html\">&lt;svg width=&quot;24&quot; height=&quot;24&quot; aria-hidden=&quot;true&quot;&gt;\n  &lt;use href=&quot;\u002Fsprite.svg#delete-24-regular&quot;&gt;&lt;\u002Fuse&gt;\n&lt;\u002Fsvg&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The sprite is downloaded and cached once, and each use is a few bytes of markup. Make the symbols&#39; paths use \u003Ccode>fill=&quot;currentColor&quot;\u003C\u002Fcode> so they still follow the text color.\u003C\u002Fp>\n\u003Ch3>External files and CSS masks\u003C\u002Fh3>\n\u003Cp>For large grids of icons (like the icon browser on this site), each icon is loaded as its own small file and drawn with a CSS mask, which keeps \u003Ccode>currentColor\u003C\u002Fcode> coloring. The browser loads them in parallel over HTTP\u002F2, caches them, and only fetches the icons that are actually on the page. See \u003Ca href=\"\u002Fguides\u002Fuse-fluent-icons-in-html-and-css\u002F\">Using Fluent icons in plain HTML and CSS\u003C\u002Fa> for the CSS.\u003C\u002Fp>\n\u003Ch2>4. Cache aggressively\u003C\u002Fh2>\n\u003Cp>Icon files rarely change. Serve them with long cache lifetimes, and put a hash or version in the file name if you ever need to update one:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>Cache-Control: public, max-age=31536000, immutable\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>If you can&#39;t version file names, a shorter lifetime (a day or a week) is a sensible compromise.\u003C\u002Fp>\n\u003Ch2>5. Avoid layout shift\u003C\u002Fh2>\n\u003Cp>Always give icons explicit dimensions, either \u003Ccode>width\u003C\u002Fcode>\u002F\u003Ccode>height\u003C\u002Fcode> attributes or CSS. An \u003Ccode>&lt;img&gt;\u003C\u002Fcode> without dimensions renders at 0&nbsp;×&nbsp;0 until the file arrives, and then pushes content around. That hurts your Cumulative Layout Shift score and is annoying for users.\u003C\u002Fp>\n\u003Ch2>6. Don&#39;t lazy-load tiny icons above the fold\u003C\u002Fh2>\n\u003Cp>\u003Ccode>loading=&quot;lazy&quot;\u003C\u002Fcode> is great for large images below the fold, but can delay small icons that are visible immediately. Lazy-load icons in long lists, not in your header or toolbar.\u003C\u002Fp>\n\u003Ch2>Checklist\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Icons minified (SVGO or already clean)\u003C\u002Fli>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Only used icons in the bundle, verified with a bundle analyzer\u003C\u002Fli>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Sprites or external files for large or repeated sets\u003C\u002Fli>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Long cache headers on icon files\u003C\u002Fli>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Explicit width and height on every icon\u003C\u002Fli>\n\u003C\u002Ful>\n",1790215639606]