DEV Community

Eka
Eka

Posted on

SVG sprites vs CSS background image for multiple instances of icons

Hi friends!

I am working on a website that requires many icons, and I am looking into using SVG sprite for the icons. Some large websites, such as Github and Codepen, use this method. If you are not familiar with it, these articles are good introductions:

In a nutshell, we have an SVG that contains of ALL our icons, grouped in <symbol> element, and we refer to each symbol by id when we want to use it.

    <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">  
      <symbol id="icon-heart" viewBox="0 0 24 24">
        <!-- <path> -->  
      </symbol>
    </svg>

    <svg class="icon">
      <use xlink:href="#icon-heart" />
    </svg>

This method also works with external SVG file, which makes caching possible, referred to like so:

    <svg class="icon">
      <use xlink:href="sprite.svg#icon-heart" />
    </svg>

So far, so good.

But performance-wise, I am curious whether it would be faster to use regular CSS background image than SVG sprite for icons that are used multiple times throughout each page?

For example, in the Codepen page below, the "view" 👁, "comment" 💬, and "love" ♥ icons are used in each "pen" card. Each page contains 12 cards.

Screenshot of Codepen Explore page

With CSS background image

Say we want to reproduce the "Love" button from the Codepen page above. If we use regular CSS background image, the minimum stripped down code would be something like this. When user goes to the next page, the CSS file would have been cached.

(Side note: PNG files would be even smaller in size but it is different in nature from SVG so I will not be discussing PNGs for background image here.)

    .icon-heart {
        padding-left: 2rem;
        background-image: url('data:image/svg+xml, <svg><path etc etc/></svg>'),url('data:image/svg+xml, <svg xmlns="http://www.w3.org/2000/svg"/>');
    }

    <button class="icon icon-heart">
        <span class="count">350</span>
    </button>

With SVG sprite

In addition to the SVG sprite file itself, the HTML code would be longer because we need to refer to the SVG. The browser has to render these three extra lines in every instance of the button (12 times in our example), and when user navigates to a new (hence uncached) page, these would be rendered 12 times again, and so on. Combined with other icons (eg. "view" and "comment" icons in the Codepen page), wouldn't it be a bloat?

    <button class="icon icon-heart">
        <svg class="icon">
          <use xlink:href="sprite.svg#icon-heart" />
        </svg>
        <span class="count">350</span>
    </button>

I haven't been able to find a satisfactory answer whether the extra lines are really insignificant in terms of page load speed in exchange for the SVG sprite's flexibility and versatility. Or is there any other consideration I am not aware about?

Any feedback or explanation would be appreciated.

Top comments (2)

Collapse
 
shanamaid profile image
Jingyi Zeng

You can use archer-svgs to load svg async and cache it in localStorage, when you reuse svg without http request!Remove svgs from your js-bunilde and Thin your js-bundle forever!(eg: Dont reload 100kb svg bundle only for 1kb svg update!)

Collapse
 
ekafyi profile image
Eka