I have a SVG image that I plan to reuse 50 - 150x times in my page, and as the page would be an infinite scroll, it could appear 1000x times or more
It is an upvote icon. I think of using the same icon, reversed, for a downvote
What is the most efficient way to include it ?
Will the HTML somehow optimize automatically the SVG code if seen many times in a page ? Or is it better to include SVG as code than as img tags ?
As long as the icon source code isn't too complicated (containing filters, animations or interpolation tasks like color gradients), rendering performance should not be much of an issue, regardless of method used.
Loading times over the net also can be minimized with loading the icon code only once, or better yet, as part of another file loaded anyway. So adding the code once inside the HTML code, a script or a stylesheet for reuse might give you a tiny advantage over using an <img>
tag.
But note that the time at which the icon becomes available for rendering might differ depending on whether you use script or stylesheet, and what priority you set via preload
and related attributes. Especially if you use a bulky JS framework, time to first render might be significantly delayed for a Component.
The most elegant technique for embeding the icon in script is the Web Component, as shown in Danny Engelman's answer.
Embedding in HTML code would need a hidden <svg>
element somewhere on the page:
<body>
<svg width="0" height="0" display="block">
<symbol id="vote" viewBox="...">
<path d="..." fill="#080" />
</symbol>
...
</body>
a bit of CSS:
.icon-vote {
display: inline-block;
position: relative;
width: 1em;
}
.icon-downvote {
transform: rotate(180deg);
transform-origin: center;
}
and some code to reference the template:
<svg class="icon-vote"><use href="#vote" /></svg>
<svg class="icon-vote icon-downvote"><use href="#vote" /></svg>
Embedding in a stylesheet would take advantage of a data url (note the URL escape of the #
):
.icon-vote {
display: inline-block;
position: relative;
width: 1em;
background: url('data:image/svg+xml,<svg viewBox="..."><path d="..." / fill="%23080"></svg>');
}
.icon-downvote {
transform: rotate(180deg);
transform-origin: center;
}
For usage, that would only need
<span class="icon-vote"></span>
<span class="icon-vote icon-downvote"></span>