skip to Main Content

I would like to know what is the best way to use SVG on an HTML document.

I’ve read an article that states, it’s better to use SVG icons than icon fonts (i.e fontawesome etc) for better performance & to reduce HTTP (network) calls. And to boost SEO also.


I know how to used/include SVG, but I have a few concerns, especially on performance and reduce network requests.

The most common one to use <img src="facebook.svg"> tag. Which I usually see from dev tools on some websites.

The other one is, by using <svg xmlns=""><path></svg> tag and,

The last one is, I put all the SVG on one single .SVG file (Sprite) and import them

<svg class="svg__icon">
   <use href="sprite.svg#facebook-icon">
</svg>

sprite.svg

<svg 
    xmlns="http://www.w3.org/2000/svg">
    <defs>

        <symbol id="user" viewBox="0 0 24 24">
            <title>User</title>
            <path fill="none" d="M0 0h24v24H0z"/>
            <path d="M4 22a8 8 0 1 1 16 0h-2a6 6 0 1 0-12 0H4zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6 6 2.685 6 6-2.685 6-6 6zm0-2c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4z"/>
        </symbol>

    <symbol id="facebook-icon" viewBox="0 0 24 24">
        <title>Facebook</title>
        <path fill="none" d="M0 0h24v24H0z"/>
        <path d="M14 13.5h2.5l1-4H14v-2c0-1.03 0-2 2-2h1.5V2.14c-.326-.043-1.557-.14-2.857-.14C11.928 2 10 3.657 10 6.7v2.8H7v4h3V22h4v-8.5z"/>
    </symbol>


    <symbol id="instagram-icon" viewBox="0 0 24 24">
        <title>Instagram</title>
        <path fill="none" d="M0 0h24v24H0z"/>
        <path d="M12 2c2.717 0 3.056.01 4.122.06 1.065.05 1.79.217 2.428.465.66.254 1.216.598 1.772 1.153a4.908 4.908 0 0 1 1.153 1.772c.247.637.415 1.363.465 2.428.047 1.066.06 1.405.06 4.122 0 2.717-.01 3.056-.06 4.122-.05 1.065-.218 1.79-.465 2.428a4.883 4.883 0 0 1-1.153 1.772 4.915 4.915 0 0 1-1.772 1.153c-.637.247-1.363.415-2.428.465-1.066.047-1.405.06-4.122.06-2.717 0-3.056-.01-4.122-.06-1.065-.05-1.79-.218-2.428-.465a4.89 4.89 0 0 1-1.772-1.153 4.904 4.904 0 0 1-1.153-1.772c-.248-.637-.415-1.363-.465-2.428C2.013 15.056 2 14.717 2 12c0-2.717.01-3.056.06-4.122.05-1.066.217-1.79.465-2.428a4.88 4.88 0 0 1 1.153-1.772A4.897 4.897 0 0 1 5.45 2.525c.638-.248 1.362-.415 2.428-.465C8.944 2.013 9.283 2 12 2zm0 5a5 5 0 1 0 0 10 5 5 0 0 0 0-10zm6.5-.25a1.25 1.25 0 0 0-2.5 0 1.25 1.25 0 0 0 2.5 0zM12 9a3 3 0 1 1 0 6 3 3 0 0 1 0-6z"/>
    </symbol>

    <symbol id="twitter-icon" viewBox="0 0 24 24">
        <title>Twitter</title>
        <path fill="none" d="M0 0h24v24H0z"/>
        <path d="M22.162 5.656a8.384 8.384 0 0 1-2.402.658A4.196 4.196 0 0 0 21.6 4c-.82.488-1.719.83-2.656 1.015a4.182 4.182 0 0 0-7.126 3.814 11.874 11.874 0 0 1-8.62-4.37 4.168 4.168 0 0 0-.566 2.103c0 1.45.738 2.731 1.86 3.481a4.168 4.168 0 0 1-1.894-.523v.052a4.185 4.185 0 0 0 3.355 4.101 4.21 4.21 0 0 1-1.89.072A4.185 4.185 0 0 0 7.97 16.65a8.394 8.394 0 0 1-6.191 1.732 11.83 11.83 0 0 0 6.41 1.88c7.693 0 11.9-6.373 11.9-11.9 0-.18-.005-.362-.013-.54a8.496 8.496 0 0 0 2.087-2.165z"/>
    </symbol>

    <symbol id="youtube-icon" viewBox="0 0 24 24">
        <title>YouTube</title>
        <path fill="none" d="M0 0h24v24H0z"/>
        <path d="M21.543 6.498C22 8.28 22 12 22 12s0 3.72-.457 5.502c-.254.985-.997 1.76-1.938 2.022C17.896 20 12 20 12 20s-5.893 0-7.605-.476c-.945-.266-1.687-1.04-1.938-2.022C2 15.72 2 12 2 12s0-3.72.457-5.502c.254-.985.997-1.76 1.938-2.022C6.107 4 12 4 12 4s5.896 0 7.605.476c.945.266 1.687 1.04 1.938 2.022zM10 15.5l6-3.5-6-3.5v7z"/>

    </symbol>

    <symbol id="pinterest-icon" viewBox="0 0 24 24">
        <title>Pinterest</title>
        <path fill="none" d="M0 0h24v24H0z"/>
        <path d="M13.37 2.094A10.003 10.003 0 0 0 8.002 21.17a7.757 7.757 0 0 1 .163-2.293c.185-.839 1.296-5.463 1.296-5.463a3.739 3.739 0 0 1-.324-1.577c0-1.485.857-2.593 1.923-2.593a1.334 1.334 0 0 1 1.342 1.508c0 .9-.578 2.262-.88 3.54a1.544 1.544 0 0 0 1.575 1.923c1.898 0 3.17-2.431 3.17-5.301 0-2.2-1.457-3.848-4.143-3.848a4.746 4.746 0 0 0-4.93 4.794 2.96 2.96 0 0 0 .648 1.97.48.48 0 0 1 .162.554c-.046.184-.162.623-.208.784a.354.354 0 0 1-.51.254c-1.384-.554-2.036-2.077-2.036-3.816 0-2.847 2.384-6.255 7.154-6.255 3.796 0 6.32 2.777 6.32 5.747 0 3.909-2.177 6.848-5.394 6.848a2.861 2.861 0 0 1-2.454-1.246s-.578 2.316-.692 2.754a8.026 8.026 0 0 1-1.019 2.131c.923.28 1.882.42 2.846.416a9.988 9.988 0 0 0 9.996-10.003 10.002 10.002 0 0 0-8.635-9.903z"/>
    </symbol>
    </defs>
</svg>

Why would I like to put them on a single sprite? I would you to preload it. If this method/technique is possible.

<link rel="preload" as="image" href="sprite.svg">

Any suggestions/corrections (upside & downside) are appreciated, just a concerned about the SEO task I was assigned to.

3

Answers


  1. I had the same thinking some times ago when I discover loading time of whole icon libraries (font awesome, google icons) even from a CDN.

    All this loading for website using 8 or 10 icons.

    I tried svg sprite, but I was always puzzled to use sprite in regular HTML CSS (mainly vertical align, sizes and color problems).

    I made github with 2 different ideas for svg library. One is how to have pure CSS svg library, second one is with using embedded svg icon. In those, icon can be easily aligned with text or other html tag, easily sized and inherit color.

    Check here:

    https://github.com/pierfarrugia/svgicons_css

    https://github.com/pierfarrugia/svgicons_embed

    You can certainly find ideas for your problem

    Login or Signup to reply.
  2. You raise some good questions here!

    Short answer: use inline SVG’s whenever you can!

    Case image/diagram:

    A separate .svg image loaded via the tag makes sense, when it should be changeable, e.g. via a CMS system by an editor. This way the SVG is handled the way an IMG is handled. It has the advantage of using vector graphics over pixel graphics for cases like icons, diagrams, etc.

    Case icon or logo: (the usual use case)

    Using inline SVG in the html code as (<svg xmlns="..."><path></svg>)replacement for font icons is a good idea since:

    1. scales better and is always sharp
    2. is easily changeable via CSS, e.g. the color
    3. loads immediately with the html and is displayed instantly since it doesn’t have to be loaded ad different file.
    4. having it multiple times on the page duplicated in the html code doesn’t matter, since gzip compression (by the server) eliminates the overhead regarding the transfer file size

    So it does not make sense to use svg sprites when you can use the SVG directly in the code.

    Please note:
    It is a good idea to cleanup SVG’s before putting them in your code, especially when thy come from graphic software like Illustrator. Best tool for that is https://jakearchibald.github.io/svgomg/. Past the code and see how it gets cleaned up.

    Login or Signup to reply.
  3. Make it a native JavaScript Web Component <svg-icon> (supported in all Browsers)

    • defined only once

    • creating the SVG client-side from minimal JavaScript

    • including its behaviour

    • So it is a Web Component you can drop into any application

    <style>  svg-icon{ width:76px;background:hotpink } </style>
    
    <svg-icon></svg-icon>
    <svg-icon is="facebook"></svg-icon>
    <svg-icon is="instagram"></svg-icon>
    <svg-icon is="twitter"></svg-icon>
    <svg-icon is="youtube"></svg-icon>
    <svg-icon is="pinterest"></svg-icon>
    
    <script>
    customElements.define( "svg-icon", class extends HTMLElement {
        connectedCallback() {
          this.style.cursor = "pointer";
          this.style.display = "inline-block";
          let icon = this.getAttribute("is") || "user";
          this.innerHTML = `<svg viewBox="0 0 24 24"><title>${icon}</title>
              ${{
                 user:     `<path d="M4 22a8 8 0 1 1 16 0h-2a6 6 0 1 0-12 0H4zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6 6 2.685 6 6-2.685 6-6 6zm0-2c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4z"/>`,
                 facebook: `<path d="M14 13.5h2.5l1-4H14v-2c0-1.03 0-2 2-2h1.5V2.14c-.326-.043-1.557-.14-2.857-.14C11.928 2 10 3.657 10 6.7v2.8H7v4h3V22h4v-8.5z"/>`,
                 instagram:`<path d="M12 2c2.717 0 3.056.01 4.122.06 1.065.05 1.79.217 2.428.465.66.254 1.216.598 1.772 1.153a4.908 4.908 0 0 1 1.153 1.772c.247.637.415 1.363.465 2.428.047 1.066.06 1.405.06 4.122 0 2.717-.01 3.056-.06 4.122-.05 1.065-.218 1.79-.465 2.428a4.883 4.883 0 0 1-1.153 1.772 4.915 4.915 0 0 1-1.772 1.153c-.637.247-1.363.415-2.428.465-1.066.047-1.405.06-4.122.06-2.717 0-3.056-.01-4.122-.06-1.065-.05-1.79-.218-2.428-.465a4.89 4.89 0 0 1-1.772-1.153 4.904 4.904 0 0 1-1.153-1.772c-.248-.637-.415-1.363-.465-2.428C2.013 15.056 2 14.717 2 12c0-2.717.01-3.056.06-4.122.05-1.066.217-1.79.465-2.428a4.88 4.88 0 0 1 1.153-1.772A4.897 4.897 0 0 1 5.45 2.525c.638-.248 1.362-.415 2.428-.465C8.944 2.013 9.283 2 12 2zm0 5a5 5 0 1 0 0 10 5 5 0 0 0 0-10zm6.5-.25a1.25 1.25 0 0 0-2.5 0 1.25 1.25 0 0 0 2.5 0zM12 9a3 3 0 1 1 0 6 3 3 0 0 1 0-6z"/>`,
                 twitter:  `<path d="M22.162 5.656a8.384 8.384 0 0 1-2.402.658A4.196 4.196 0 0 0 21.6 4c-.82.488-1.719.83-2.656 1.015a4.182 4.182 0 0 0-7.126 3.814 11.874 11.874 0 0 1-8.62-4.37 4.168 4.168 0 0 0-.566 2.103c0 1.45.738 2.731 1.86 3.481a4.168 4.168 0 0 1-1.894-.523v.052a4.185 4.185 0 0 0 3.355 4.101 4.21 4.21 0 0 1-1.89.072A4.185 4.185 0 0 0 7.97 16.65a8.394 8.394 0 0 1-6.191 1.732 11.83 11.83 0 0 0 6.41 1.88c7.693 0 11.9-6.373 11.9-11.9 0-.18-.005-.362-.013-.54a8.496 8.496 0 0 0 2.087-2.165z"/>`,
                 youtube:  `<path d="M21.543 6.498C22 8.28 22 12 22 12s0 3.72-.457 5.502c-.254.985-.997 1.76-1.938 2.022C17.896 20 12 20 12 20s-5.893 0-7.605-.476c-.945-.266-1.687-1.04-1.938-2.022C2 15.72 2 12 2 12s0-3.72.457-5.502c.254-.985.997-1.76 1.938-2.022C6.107 4 12 4 12 4s5.896 0 7.605.476c.945.266 1.687 1.04 1.938 2.022zM10 15.5l6-3.5-6-3.5v7z"/>`,
                 pinterest:`<path d="M13.37 2.094A10.003 10.003 0 0 0 8.002 21.17a7.757 7.757 0 0 1 .163-2.293c.185-.839 1.296-5.463 1.296-5.463a3.739 3.739 0 0 1-.324-1.577c0-1.485.857-2.593 1.923-2.593a1.334 1.334 0 0 1 1.342 1.508c0 .9-.578 2.262-.88 3.54a1.544 1.544 0 0 0 1.575 1.923c1.898 0 3.17-2.431 3.17-5.301 0-2.2-1.457-3.848-4.143-3.848a4.746 4.746 0 0 0-4.93 4.794 2.96 2.96 0 0 0 .648 1.97.48.48 0 0 1 .162.554c-.046.184-.162.623-.208.784a.354.354 0 0 1-.51.254c-1.384-.554-2.036-2.077-2.036-3.816 0-2.847 2.384-6.255 7.154-6.255 3.796 0 6.32 2.777 6.32 5.747 0 3.909-2.177 6.848-5.394 6.848a2.861 2.861 0 0 1-2.454-1.246s-.578 2.316-.692 2.754a8.026 8.026 0 0 1-1.019 2.131c.923.28 1.882.42 2.846.416a9.988 9.988 0 0 0 9.996-10.003 10.002 10.002 0 0 0-8.635-9.903z"/>`
                }[icon] || console.error("invalid is:", icon)
               }</svg>`;
          this.onclick = (evt) => {
            console.log("clicked:", icon);
          }
          this.onmouseenter = (evt) => this.style.background = "green";
          this.onmouseleave = (evt) => this.style.background = "pink";
        }
      }
    );
    </script>

    If you want to take this N steps further; see: https://iconmeister.github.io

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search