aztrorisk
aztrorisk

Reputation: 171

Is it possible to combine all SVG icons into one file for performance in HTML?

I have a bunch of different SVG files in my public folder. These svg are shown using the image-mask: url(/icon.svg) attribute.

This is fine if I only had one svg but I have 20 different icons. Is there a way to combine it into something like sprites for regular JPG images?

Thanks!

Upvotes: 2

Views: 6123

Answers (3)

edwin
edwin

Reputation: 2821

Yes. You can use tools to combine multiple SVG files into a single sprite sheet using tags. This is supported by all modern browsers.

You can do this from a Node.js script using svgstore: https://github.com/svgstore/svgstore

There's also a cli variant you can use from a npm (package.json) script or from the command line: https://github.com/svgstore/svgstore-cli

Upvotes: 2

Zlatin Zlatev
Zlatin Zlatev

Reputation: 3089

Have a look at https://www.lambdatest.com/blog/its-2019-lets-end-the-debate-on-icon-fonts-vs-svg-icons/#:~:text=How%20To%20Build%20Your%20SVG%20Icon%20System%3F

In a nutshell:

  1. Convert an icon font to SVG using tool like https://onlinefontconverter.com/
  2. Edit the SVG by selecting just the symbols you need using tools like
  3. Use syntax like <svg class="icon-twitter"><use xlink:href="#icon-twitter"></use></svg> to address parts of the locally included SVG.

Upvotes: 0

Rounin
Rounin

Reputation: 29453

One performance approach you can look at is adding your SVGs to your CSS Stylesheet as Data URIs.

This has one downside:

  • it increases the size of your CSS stylesheet

but the following two advantages:

  • You won't need to undertake the server round-trips to collect the SVGs
  • When the browser caches your stylesheet, all your inlined Data URI SVGs will be cached, simultaneously, along with the stylesheet

This will almost certainly give you a noticeable performance boost.


Let's have a look at how this might work.

Here's an SVG for a five-pointed star:

<svg xmlns="http://www.w3.org/2000/svg" width="260" height="245">
<path transform="scale(0.75)" d="m55, 237 74-228 74, 228L9, 96h240" />
</svg>

And here's that same SVG as a Data URI:

data:image/svg+xml,%3Csvg%20xmlns="http://www.w3.org/2000/svg"%20width="260"%20height="245"%3E%3Cpath%20transform="scale(0.75)"%20d="m55,237%2074-228%2074,228L9,96h240"%20/%3E%3C/svg%3E

You can see that after the data:image/svg+xml, prefix, the Data URI SVG is almost exactly the same, except:

  • the angle brackets < & > have been swapped for %3C & %3E percent codes

Finally, here's that Data URI SVG in action in the CSS below...

Working Example:

.image-without-mask,
.image-with-mask {
  float: left;
  width: 200px;
  height: 180px;
  margin-right: 12px;
}


.image-with-mask {

  /* N.B. -webkit- prefix required for Chrome, Edge, Safari and Opera (but not Firefox) */
  -webkit-mask-image: url('data:image/svg+xml,%3Csvg%20xmlns="http://www.w3.org/2000/svg"%20width="260"%20height="245"%3E%3Cpath%20transform="scale(0.75)"%20d="m55,237%2074-228%2074,228L9,96h240"%20/%3E%3C/svg%3E');

  mask-image: url('data:image/svg+xml,%3Csvg%20xmlns="http://www.w3.org/2000/svg"%20width="260"%20height="245"%3E%3Cpath%20transform="scale(0.75)"%20d="m55,237%2074-228%2074,228L9,96h240"%20/%3E%3C/svg%3E');
}
<img class="image-without-mask" src="https://via.placeholder.com/200x180/0000FF/FFFFFF" />

<img class="image-with-mask" src="https://via.placeholder.com/200x180/0000FF/FFFFFF" />

Upvotes: 6

Related Questions