Why is SVG so slow!

While working on the TunedIn web App i came across an issue with SVG.

As we want to be retina ready and be able to easily switch colors of icons. We decided to use SVG for our icons. This worked well as SVG is nicely embeddable into HTML.

By using the svg.whateverClass { fill: #fff; } css property you can change the color of the icon or add shadows and stroke colors.

This worked all nicely until i had a lot of elements repeating the same SVG icons. I use chrome as my development browser (which is quite fast) so it took a while for me to notice. But as i tested in safari scrolling of many elements became heavily slow!

I checked if there were to many events or the retina sized images of the items were the cause, until i removed the SVG rating icons… and bam! everything was super fast again!

The problem was also actually the amount of SVG vectors the browser had to render. The more elements there are, the more slow you website will get.

The follwing graphic show pretty good how the number of SVG elements will drain performance exponentially.

SVG Performance vs Canvas

As i used the same icon over an over again i thought i can reuse the SVG using the <defs> and <use> tags.

I stored the SVG in an hidden container before the closing </body> tag and defined all icons inside the <defs> tag like this:

(yes you can reuse them before you define them)

<!-- use the icon somewhere in your website -->
<svg viewBox="0 0 1000 1000" version="1.1">
    <use x="0" y="0" xlink:href="#icon1"/>
</svg>

...

<svg viewBox="0 0 1000 1000" version="1.1">
    <use x="0" y="0" xlink:href="#icon2"/>
</svg>

...

<!-- define the icons -->
<div class="svgContainer" style="display: none">
    <svg viewBox="0 0 1000 1000" version="1.1">
       <defs>
           <g id="icon1">
               <circle id = "s1" cx = "200" cy = "200" r = "200" fill = "yellow" stroke = "black" stroke-width = "3"/>
           </g>
           <g id="icon2">
               <ellipse id = "s2" cx = "200" cy = "150" rx = "200" ry = "150" fill = "salmon" stroke = "black" stroke-width = "3"/>
           </g>
       </defs>
  </svg>
</div>
</body>

but even this, didn’t made the site faster, but i think its a better way to reuse SVG icons as defining them over and over again.

So how to deal with this?

After trying for hours to write the SVG icons on-the-fly to a canvas element, i came back to @font-face web-fonts.

And guess what? Converting the same icons to a web font and displaying them was the solution. Now the app is fast and i still have the possibility to change the color and size of the icons on the fly, by setting the color: #fff; property!

How to transform SVG into a Web-Font?

Save your icons into several *.svg files and give them the name the icon should have. After that upload them to icomoon.io/app/ and generate you web-font.

You can also use fontcustom.com or the grunt task github.com/sapegin/grunt-webfont, but they didn’t worked with my SVG files 🙁

Image Source: http://smus.com/canvas-vs-svg-performance/

  • Pingback: Where are we at with SVG performance?CopyQuery CopyQuery | Question & Answer Tool for your Technical Queries,CopyQuery, ejjuit, query, copyquery, copyquery.com, android doubt, ios question, sql query, sqlite query, nodejsquery, dns query, update query()

  • christopheschwyzer

    Thanks for article. We’re using icon fonts right now, but are not 100% happy with it and wanted to switch to SVG. Have a look at this article: http://ianfeather.co.uk/ten-reasons-we-switched-from-an-icon-font-to-svg/ About the performance – you’re referencing a performance chart from 2009 – I guess, newer browser versions improved the performance. I try to re-evaluate the performance impact.

    • frozeman

      thanks for the hint.
      the performance i experienced was in chrome and safari just 4 month ago.
      SVG are probably nice, but not for many icons. We had 5 ratings starts per movie, for 50 movies on a page and it then got sluggish.

      whats the problems you’re having with font icons?

      • christopheschwyzer

        Apart from the points in the above quoted link, icon fonts are great and probably still the best way to use icons in “normal” circumstances. For some special UI elements I wanted to use animated icons – that’s why I was looking for other solutions.
        The only way seems to be inline SVG (Like you described). This gives you much more flexibility and the option to animate (see http://tympanus.net/codrops/2013/11/27/svg-icons-ftw/)

        I created a paint-performance test with different icon usages: https://github.com/christopheschwyzer/icon-paint-performance) I can confirm that in Chrome paint-performance of the font and Inline SVG are comparable (and way faster than if icon is included via background-image). Will try to “evaluate” other browsers as well.

        • frozeman

          Nice test repo!
          SVG seems to get up in speed, could you try safari as ell, would be interesting to see.

  • Anatidae

    For all its failings, Flash developers had these same issues a decade ago. The adobe player solved it by caching vector images as bitmaps. Of course, if you scale the vector, it swaps back to a vector for the transformations (at a loss of performance again). It is a great solution though.

    It would be great if the browsers lifted the code in the font engines and applied that to SVG graphics. Clearly it is more of an optimization issue more than anything else.

  • Remco Vlierman

    old article, but it still hold true to some extend. You won’t run into problems with svg in ‘normal’ use cases. But recently I had an app width a pretty big data set, with about 400 rows, and 6 svg icons per row…. Desktop no problem at all, but performance chrashed in iOs, and tablets…. Pure on CPU power.
    Replacing the icons with a icon-font did the trick. just putting it out here fore reference

  • Sergiu Ojoc

    It works with monochromatic icons, you can convert them to fonts, what to do when you have let’s say, countries flags icons?
    SVG sprites don’t work in safari.