Making the most of SVG symbols for optimal file size
SVGs are excellent for providing crisp, vector artwork on the web - a useful ally in reducing your overall file-size and optimising for speed.
In our recent work developing Double Fine's new website, we made extensive use of SVGs across the site design. In our quest to keep page sizes low, we learnt a few new tricks with SVG symbols to really crunch the numbers down on our decorative SVGs. Symbols in SVGs are essentially references to artwork within the SVG document. They allow you to draw something once and reference it elsewhere with the
Here's a few examples of our process and the kinds of results we were able to get with SVG symbols.
Example 1: Repeating borders
In this first simple example, we have a decorative border which repeats around the outside of an oval. We've got our artwork in Sketch and we're ready to export to bring our artwork in to the web page.
Ironically, our original artwork was first drawn in Illustrator, then brought over in to Sketch to create page mocks. This was ideal for the design stage, using Sketch's symbols and component library tools. But now it's time to export - and Sketch underperforms. The shape itself is a single path, which is inefficient, but Sketch doesn't have the tools we need for optimising this image to use SVG symbols, so we bring the artwork over to Illustrator.
Identifying the symbols
Once we're back in Illustrator it's time to start looking at how the file can be divided up in to repeatable regions. The most obvious one is the single point which repeats all around the border.
To create a symbol we first need to draw the path. Keeping the original image visible on a layer underneath, we trace the shape of our single border point. Giving it a large "foot" underneath will later help us to overlap it with adjacent points on our border. Opening up the symbols palette in Illustrator, we can convert our path in to a symbol by simply dragging and dropping it on to the symbols palette. But how do we create the repeating border with it? Well - there are no shortcuts here. Still using the original image underneath as a guide, we place each border point symbol on to the border. Copy, paste, reposition, copy, paste and reposition - rinse and repeat.
Once we've completed an entire quarter, we can stop. Because our border pattern is symmetrical, we can now create our second symbol - a quarter section. This symbol won't contain any paths or shapes - just the border point symbol, repeated from our masterfully executed copying, pasting and repositioning exercise.
With the quarter section complete, we convert it into a symbol and place three more copies on the stage. Flip vertical, flip horizontal and we've got our full border image. A small amount of tweaking is needed to get the border even. Then we just need to add a circle shape to fill in the middle, and we're done! After exporting from Illustrator, our final step is to run the file through SVGO for our last bit of byte-saving.
So, how does our effort fair on the file reduction side of things? Well, its a huge reduction from the original export, 93% smaller. Sketch doesn't round integers when exporting SVGs, so our original export has some extremely high accuracy of 7 or 8 decimal places on its path coordinates. Moving the file to Adobe Illustrator instantly improves that as it provides decimal rounding to two decimal places by default. The subsequent work within Illustrator is a little lengthy but also very satisfying to get such a good result - with our final file size being just 3.7KB.
|Original Sketch export.
|Illustrator export using symbols.
|Compressed with SVGO.
|49.3KB saved, 93% smaller 🥳
Example 2: Text banner
For our next example, we have a decorative banner containing text with not only a gradient fill but also two strokes applied to it - not something which SVG supports with text out-of-the-box.
Identifying the symbols
Let's start with the easy one - the background. We've got a banner running behind the text and draping down either side. The symmetry here can easily be turned in to a symbol, which we can then duplicate for the opposing side. The top part of the banner is simple and we kept as a path, the symbol then sits underneath.
Now we've got all we need for the scroll, we can move on to the text. This is where things get a bit more interesting. At first, we tried using an SVG
text element, great for accessibility and we can style the text by placing it on a path. But we can't directly recreate the skewed effect of the text on that path, and neither can we apply multiple strokes to the text. So if we want the design to stay the same, we'll need the text to remain as outlines.
With the text as paths, however, we're offered an opportunity to reduce the complexity of the paths by using Illustrator's "Simplify" functionality. A vital step! We opted for about 86% quality, with which we found very little discernable difference (typographers, disagree here).
Once we have the outlines, there's obvious repetition we can spot. Any letter that appears more than once is surely an opportunity for a symbol to replace it, isn't it? Well, yes - and just like placing the border points around the outside of the border example, here we can convert each letter to a symbol - at least, those letters which appear more than once. Again, using our original image underneath we can skew and move each letter into its correct position. Typesetting every character! This is now officially a labour of love.
Once we've converted our letters to symbols, we can convert all the text into its own symbol, which we'll call "words".
From this point on there's a good amount of optimisation work to be done in the SVG file itself. So after a final export from Illustrator, it's time to get our hands dirty in the code editor.
In the SVG file, using our new words symbol, we can achieve multiple strokes on the text. An SVG
g element can have a stroke applied. So we simply wrap the words symbol with a group, duplicate - and then apply our different strokes. We start with a wide stroke below and a narrower one above which creates the effect of multiple strokes.
<g stroke-width="7.5" stroke="#BF200B" stroke-linejoin="round" stroke-linecap="round"> <use width="886" height="160" xlink:href="#words"/> </g> <g stroke-width="2.5" stroke="#FFAF00" stroke-linejoin="round" stroke-linecap="round"> <use width="886" height="160" xlink:href="#words"/> </g> <use width="886" height="160" xlink:href="#words"/>
There's some more tidying up to do. Gradient fills work in the same way as symbols, defined in the
defs area of the SVG markup and we found that in our files, a few improvements could be made by merging similar ones and reducing the overall number of them. Since our text was converted to outlines, we also need to add the text back in somewhere to ensure it's machine-readable for accessibility.
Our original image was a massive 392KB. The Sketch export was especially underwhelming as it embedded bitmap images for the gradients on the text, rather than use native SVG gradients. Because of this, our initial filesize is a bit misleading but it was nonetheless our starting point from which to improve upon.
The conversion to Illustrator is then huge, and we continue to make savings through manually editing and modification with SVGO. Our final size then comes out at 13.1KB - not bad for a file with text paths.
|Original Sketch export.
|Illustrator export: Heavily edited, paths simplified, paths converted to symbols wherever possible.
|Manually edited, adding colour and gradients.
|Compressed with SVGO.
|378.9KB saved, 96.6% smaller 🥳
We created many SVGs for the Double Fine website project and were able to master the use of SVG symbols with these sorts of techniques over time. It's a shame that Sketch doesn't yet support SVG symbols, but the tools available in Illustrator are established and work well for prepping your artwork for export with symbols embedded.
Posted by Tom Kiss on February 5th 2021.