© Alex Libby  2018
Alex LibbyBeginning SVGhttps://doi.org/10.1007/978-1-4842-3760-1_7

7. Optimizing SVG

Alex Libby1 
(1)
Rugby, Warwickshire, UK
 

So far, we’ve learned how to create basic shapes, manipulated website content, and applied effects to imagery – this is great, but there is one thing we should also consider: some SVG content can be a little bloated, so there is always room for optimizing our content. Over the course of the next few pages, we’ll look at some of the pain points where content might be less than optimal, and cover some of the tips and tricks we can use to ensure our content is working at optimal efficiency.

Exporting SVG Images for Use

When working with SVG, it’s all too easy to simply hit the export button to save content as an SVG file – most packages such as Illustrator, Sketch, or even the online tool Vectr make it a real cinch to save our work.

The trouble is, we will frequently end up with bloated content – take, for example, this extract of code from an SVG image:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns:="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
        width="612px" height="792px" viewBox="0 0 612 792" enable-background="new 0 0 612 792" xml:space="preserve">

It is perfectly valid code, but most of it is unnecessary and can be safely discarded. In many cases, we can reduce this through more judicious use of features in our SVG; as an example, Sarah Soueidan has a great article on how making some simple changes in an application such as Illustrator can already begin to reduce our code.

You can see the full article at https://www.sarasoueidan.com/blog/svg-tips-for-designers/  – it is a couple of years old, but the principles within are still relevant.

Getting to the point where we have an exported image will, of course, vary from package to package; the exact processes required are outside of the scope of this book. We will going forward assume we have something that has already been optimized and is ripe for optimization. There will be plenty we can do, but before we do so, there is one thing we should cover off first – that is answering the question: Why is it important to optimize our SVG content?

Understanding the Importance of Optimization

At this point, we now have a set of exported images – we can drop these into a page, add some content, and away we go, right…? Wrong. Sure, our page will display – people will see our content…eventually. But I will lay very good odds that it will be slow, cumbersome, and in many cases, people will vote with their feet. As the developer Brad Frost once said:

The road towards better performance doesn’t start with developers or technology stacks (though I’m certainly not suggesting those things are unimportant). It begins with a shared interest on everyone’s part in making a product that’s lightning fast.

I recommend reading the original article by Brad Frost at http://bradfrost.com/blog/post/performance-as-design/  – it may be a few years old, but many of the principles still hold true!

To prove how important it is, imagine you have a small site, with only 50 pages. Navigating this won’t be an issue, but imagine this has been scaled up by a factor of 60. It’s going to start getting slower to navigate – and that may only be static pages! Just imagine what it would be like for a dynamic site serving in the region of 500,000-plus products…

In an age where mobile is rapidly overtaking desktop as a platform of choice, performance is king – pages that have not been optimized will directly affect the user experience and have an impact on page metrics. This may be less apparent on desktops, but the impact will be exacerbated by the lower connection speeds on mobile devices, which is now the platform of choice for many individuals around the world.

Now – this isn’t to say that SVGs are the only items that need to be optimized; everything being referenced on the page must be fine-tuned for optimal performance. However, SVGs can contain a lot of extra content such as meta tags, values that run to several decimal places or extra nodes that are not always necessary.

In many cases, designers who create SVGs will optimize images as part of the design process. However, this may not always happen – it’s up to us as developers to ensure that images have been optimized, so that this extra cruft is removed, while maintaining the desired look and feel as created by the designer. It may only be a few bytes here and there that we remove, but these will all add up over time!

The great thing about SVGs, though, is that they are easy to optimize – there are a few tricks we can use to remove redundant content and bloat from our images and still keep the look and feel that we need for our site. To see what a difference we can make, let’s begin first with a look at where we can make changes to improve the performance of our SVG images.

Assessing Performance

Once our images have been exported, the next stage in development should be to optimize them – many of the principles we use for HTML, CSS, and JavaScript can also be used to remove cruft from our SVG images.

The process comes in two parts – we should run each image through an optimization process, but then spend time tweaking images to fine-tune each to optimal efficiency. It’s worth noting that for some images this isn’t sensible (if they are really small or simple), but for larger images there may be additional changes we can make that have not already been implemented by optimization tools.

Most of the process can be done automatically for us (as we will see shortly, in the section “Shrinking Images with SVGO”), but it is worth understanding some of the key areas where we can make changes to help improve the performance of our SVG images:
  • Check the size of your canvas – this may be larger than necessary, which will increase the file size of your SVG graphic.

  • How many decimal places do the values in your SVG have? If they have lots, then consider dropping them down to whole integers, or at least removing some of the precision, making your files smaller and faster.

  • Does your source graphic contain lots of gradients, and store these in the <defs> block at the start of the SVG? If so, it’s worth checking them: if there are lots present, then try running the code through the gradient optimizer tool available on Codepen at https://codepen.io/ jakealbaugh/full/OVrQXY. This will collapse any unused gradients into those that are needed for your SVG graphic, which will reduce the file size and increase performance.

  • If we have multiple shapes within our SVG that are very similar, we can consider making use of the use statement; thus:
    <svg height="300" width="400" viewBox="0 0 300 400">
      <defs>
        <rect id="sourceRec" x="0" y="0" height="300" width="400"/>
      </defs>
      <use href="#sourceRec" fill="#57A0C3" x="0" y="0" />
    </svg>
This will reuse a predefined shape that is already in the <defs> block, reducing the need to create new shapes.
  • Make use of CSS sprites to store multiple SVG images; this works really well for this format.

  • If you are only making use of a handful of SVG images, then consider putting them inline to your code – this will reduce the number of HTTP requests made, but this is at the cost of losing caching (so not suitable for lots of SVG images!)

Now – I should point out that these changes are not the only ones we should consider making; many of the changes include smaller tweaks, such as removing redundant XML instructions. We’ll take care of many of these smaller changes through using the optimization tool, but as we will see later in this chapter in Learning How to Micro-optimize Content,” we can fine-tune our SVG content further, for optimal efficiency.

Talking of micro-optimizing though, we have an obligation to ensure our content remains accessible to all who visit our pages; depending on your analytic metrics, we may have a need to adjust our images to allow for users of assistive technology (such as screen readers).

The downside is that there aren’t any tools available to automatically make images accessible – sorry to disappoint: this is one area where we might have to get dirty with code! However, before we get stuck in with code, there are a few things to consider; let’s dive in and take a look at the practicalities involved.

Taking Care of Accessibility

Anyone who uses your website may have a disability – this might be visual, cognitive, hearing, or motor-based; it might even be a case of that individual suffering from nothing more than a broken arm or be forced to use older equipment when surfing the web.

Although the need to comply with accessibility legislation may differ from country to country, accessibility should be considered as part of the development process; there is always a risk that we might be sued if our content isn’t made accessible. A good starting point for any existing site is to check metrics – what do they tell us?

If the metrics show little use then we should work out the reasons for this – is it that our offer is such that it will not appeal to users of assistive technologies? Or – is it more likely that our site needs work to make it more accessible? This might range from something simple as adding ARIA tags, through to developing content for a completely new platform; in many cases customer feedback will help determine priorities for implementing these changes.

Assuming we establish a need to make our content more accessible (and in this instance, SVG in particular), there are a few steps we can take to facilitate this process. This will depend a little on whether our SVGs are held inline or externally; let’s take a look first at what we might need to change or add for externally hosted images:
  • If we’re including SVG images externally, then alt tags should always be used for important images.

  • External images should include an ARIA role='image' attribute, as some browsers may ignore images that do not have an alt tag present.

ARIA, or WAI-ARIA to give its full name, is a specification created by the W3C, to provide a set of attributes that can be applied to elements to help improve accessibility, such as those who use screen readers.

  • If our external SVG image is purely decorative, then include an empty alt=" tag; otherwise a screen reader may read the source tag, which will sound awful!

Adapting images that are hosted inline is a little more involved, but nothing complex – we should make the following changes to any SVG that is important for the site, and not those that are there for decorative purposes only:
  • Each SVG we create should have a <title> tag within the definition, directly below the opening <svg> tag. It should be brief – treat it in the same way as we might for an <alt> attribute tagged against an image.

  • In the SVG tag, add an aria-labelledby attribute that points to the <title> tag.

  • As an optional (but recommended) extra, consider including a longer <desc> tag (description) in addition to the title tag – this is very helpful for users of assistive technology. The <desc> tag should communicate the purpose or design of the SVG.

  • If we want to include text within our SVG, then use the <text> tag; standard text can’t be detected by screen readers, search engines and makes for a poor UX experience when resizing or being read by people with low vision.

  • If there is more than one shape, you may want to consider including separate title tags for each shape group.

Allowing for these changes, let’s take a look at an example block of code, to see they would look (changes are highlighted in bold):
  <svg aria-labelledby="title">
    <title id="title" lang="en">Red Rectangle</title>
    <desc id="details">A red rectangular shape</desc>
    <rect x="0" y="0" width="100" height="50" fill="red" />
  </svg>

As we’ve seen from this code block, making an image more accessible isn’t difficult – it will require time and effort to plan and implement the changes, which should be prioritized according to demand and the scale of work required. The best way to see what is involved is to implement the changes to a real image, so without further ado, let’s dive into our next exercise to see what is required in practice.

Making Content Accessible

For our next exercise, we’ll use one of the Open Iconic icons, hosted at https://useiconic.com/open . It’s a great source of SVG icons for all manner of uses and is also perfect for testing the code changes we’ll make in our demo. We’ll apply the same accessibility principles that we’ve just discussed to this image, so you can get a feel for how easy it is to amend the markup in any SVG image.

MAKING AN IMAGE ACCESSIBLE

Let’s make a start on that demo – this time around, we will use Codepen to host it:
  1. 1.

    We’ll start by extracting a copy of the accessible folder from the code download that accompanies this book – save it to the root of our project folder.

     
  2. 2.

    Next, browse to http://www.codepen.io , then go ahead and paste the code from within accessible.txt file into the HTML frame.

     
  3. 3.

    There a single style rule we should apply, for our demo to work correctly, so go ahead and paste in the contents of the accessible.css file into the CSS frame.

     
  4. 4.
    We can now alter our code to make it more accessible – for this, go ahead and add in the aria-labelledby tag, as indicated:
    <div class="icon-container" aria-labelledby="title">
     
  5. 5.
    Next, add in the following two lines of code immediately below the opening <svg> tag – these are the title and description tags that we talked about earlier:
        <title id="title" lang="en">Shopping Basket</title>
        <desc id="details">A typical shopping basket for an e-commerce site</desc>
     
  6. 6.

    If all is well, we should have something akin to the code shown in Figure 7-1 – you can see the finished article at https://codepen.io/alexlibby/pen/BrqQRj .

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig1_HTML.jpg
Figure 7-1

Making our SVG image accessible

Shrinking Images with SVGO

When working with SVG images, there should always be one task that we complete for any image – we should optimize it, no matter what the size or its complexity. Granted, a smaller image won’t show a great deal of improvement in size, but larger ones certainly will; there should be no excuse for not optimizing our content, and putting bloated SVGs onto a diet, so to speak!

Thankfully there are several tools available that help make this process a breeze – one of the most popular solutions is the Node.js-based tool, SVGO. This tool comes in three flavors: the original Node.js version, versions that can be used with task runners such as Grunt, or through an online version available at https://jakearchibald.github.io/svgomg/ .

This last version will be the subject of our next demo – this uses the same settings as the original tool but makes the changes in real time; we can easily see the impact of how something will look, before committing it to disk through the Node.js version.

Optimizing Manually

The first option for optimizing our SVG images comes in the form of the online SVGOMG tool (or SVGO’s Missing GUI). Created by Jake Archibald, this tool makes it very easy to see what happens when optimizing an image. It’s perfect for single-use instances, or to help get accustomed to what we might expect to see when optimizing images.

We will cover how to automate this process using Node.js, but for now, let’s get stuck in and see how the process works in more detail.

USING SVGO ONLINE

Let’s make a start with optimizing our image:
  1. 1.

    We’ll begin by extracting a copy of our source image – it’s in the code download that accompanies this book, within the svgonline folder.

     
  2. 2.

    Next, let’s browse to the online version of SVGO , which is at https://jakearchibald.github.iosvgomg/ .

     
  3. 3.

    Once on the site, click on Open SVG, then browse to our project folder and select the source image.

     

You can equally drag and drop the image onto the page if preferred – drag it over the gray area to activate the optimization process.

  1. 4.

    The image will load and be optimized automatically, using the default settings, as shown in Figure 7-2.

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig2_HTML.jpg
Figure 7-2

Optimizing our image using SVGO

  1. 5.

    Go ahead and click on the white arrow pointing downward to download our image, as indicated in Figure 7-3.

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig3_HTML.jpg
Figure 7-3

Downloading our SVG image

  1. 6.

    We should at this point run one final check – go ahead and open the image that we’ve just optimized; it’s in the optimized image folder within the code download that accompanies this book. Check to make sure it still shows as the original image – if all is well, you shouldn’t see any noticeable difference!

     

A drop of 6KB in size for our optimized image may not see a great deal in itself. However, this should always be seen as part of the bigger picture – anything we can reduce while not impacting on the overall appearance will help improve the overall speed of our site.

In many cases, the default settings will be sufficient, but there may be occasions where changing the settings might result in additional savings. The beauty about using this route is that the changes are instantaneous – they are not committed until we hit the download button. To see what I mean, let’s dive in and take a look at how this demo works in more detail.

Understanding How It Works

The online SVGOMG process hides a lot of the work required to optimize SVG images – it makes it a breeze to run the process on our content. This is one of those tools that follow the 80:20 rule; we may only have 20% of the work to do, but 80% of it is done for us through the tool automatically.

The tool exposes most (if not all) of the optimization options of SVGO, so it is perfect for learning how the tool works, and what settings we should use to get the best result from the process. For us, it’s a matter of dragging and dropping an image on the page, then moving the sliders left or right to enable or disable a specific optimization feature.

For example – if we move the Precision slider to the far left, this activates the cleanupNumericValues plug-in option within SVGO. Moving it to the left reduces the precision down to whole integer values only (and reduces the size), but moving it to the right will increase precision and increase the file size.

To help understand what each setting does, I have included a PDF ("SVGO Properties”) in the code download that lists the full set of attributes that can be enabled or disabled – in many cases, simply leaving them as they are by default will be a good starting point. However, it’s worth trying them out over a period of time – not every SVG graphic will have the same attributes specified, so a bit of trial and error will be required to achieve the best optimization!

A word of note – you will see that the file sizes shown in Figure 7-3 don’t appear to correspond with what is stored on your PC. This is deliberate – the smaller sizes mean that the “Compare gzipped” option is enabled; slide this to the left to show the real file sizes.

Okay – let’s move on: running the process manually works well, but it will soon become limiting; there is no way we have time to optimize lots of images by hand, when we have better things to do! Question is: Can we automate our process?

Automating the Optimization Process

Absolutely we can! The option I have in mind uses the same SVGO tool we’ve just used in the previous demo, but this time we’ll use it through a task runner, with Grunt as our example. This demo will come in two parts – we first have to install Node.js and test that it works, before adding in our plug-in to use SVGO with Grunt.

Don’t worry if Grunt is not your task runner of choice: there are plug-ins available for dozens of other systems, such as PostCSS, Gulp, and Broccoli.

We will use our original coffee addict image from the previous demo – you can download a fresh copy if needed, from https://www.freesvgimages.com/just-another-coffee-addict/ . Let’s take a look at what is involved in more detail:

OPTIMIZING USING TASK RUNNER – PART 1

For the purposes of this demo, we will assume we’re starting with a new installation of Node.js and Grunt – if you already have it installed from the previous chapter, then please skip straight to step 2.

  1. 1.

    Install Node.js according to instructions from site for your chosen platform – accept all of the default settings, which will be sufficient for this demo.

     
  2. 2.

    Next, go ahead and extract a copy of the svgopt folder to your project folder.

     
  3. 3.

    We now need our coffee addict image – go ahead and save a copy from the code download that accompanies this book, into the svgopt folder we created in step 2, as addict.svg.

     
  4. 4.

    Now run Node.js command prompt (or terminal session, for Mac users) as local administrator, then change the working folder to the svgopt folder stored in our project folder.

     
  5. 5.

    At the prompt, enter npm install –g svgo then hit Enter – it will go ahead and install SVGO.

     
  6. 6.

    Once the install has completed, type svgo in/addict.svg out/addict.svg at the prompt, then press Enter – Figure 7-4 shows the image has been successfully optimized, with a 15.2% (or just over 6KB) saving.

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig4_HTML.jpg
Figure 7-4

Results of optimizing our image

  1. 7.

    We can now preview the results – if all is well, we should see something akin to the image shown in Figure 7-5; we should not see any visual change but can rest happy in the knowledge that it has been optimized.

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig5_HTML.jpg
Figure 7-5

Previewing our optimized image

At this point, we now have SVGO installed and working, using Node.js – this means we can optimize images locally, without having to rely on using the online version of the SVGO tool. It’s a great way to test changes, but there is something to be said for being independent!

That said, running a command-line operation is still a manual process – let’s correct that, by adding in Grunt to run the SVGO tool over multiple files in one pass.

OPTIMIZING USING TASK RUNNER – PART 2

Let’s make a start with updating our installation:
  1. 1.

    We’ll begin by firing up a Node.js command prompt session (or terminal session, for Mac users); at the prompt, go ahead and type this command, then press Enter: npm install –g grunt-cli

     
  2. 2.

    Next, we need to create a package.json file, which contains details of the packages we will use for our optimization process. For this, enter the following command at the prompt, then press Enter: npm init –-yes

     
  3. 3.

    Node will run through the process of creating the file automatically using default values from within the folder and save it to our folder. Once completed, we will see something akin to the screenshot shown in Figure 7-6: Enter after each question, or to accept the default shown in brackets.

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig6_HTML.jpg
Figure 7-6

Details for the package.json file

  1. 4.

    After the last entry (the license), it will display your values, then prompt you to confirm it is OK – press Y or Enter to accept the values.

     
  2. 5.

    With our package.json file created, we can now install Grunt, using this command: npm install grunt --save-dev.

     
  3. 6.

    Next up comes the core of our optimization process – we need to install the Grunt plug-in for SVGO: npm install grunt-svgmin --save-dev (as shown in Figure 7-7).

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig7_HTML.jpg
Figure 7-7

Installing grunt-svgmin

  1. 7.

    We have one last tool to install – grunt-watcher, which looks out for changes to our folder, and runs the optimization process: npm install grunt-watcher --save-dev

     
  2. 8.

    The next task is to set up our Gruntfile – this has already been created for us and should be present at the root of our svgopt folder.

     
  3. 9.

    We now have everything installed and configured – time to try it out! Go ahead and fire up a Node.js command prompt session (or terminal session, for Mac users), then change the working folder to the svgopt folder and entering grunt svgmin, as shown in Figure 7-8.

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig8_HTML.jpg
Figure 7-8

Testing our setup

  1. 10.

    Assuming we get a positive result, we can now test the process – for this, enter the command grunt at the command prompt, then press Enter (Figure 7-9).

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig9_HTML.jpg
Figure 7-9

Testing our Grunt setup

  1. 11.

    Go ahead and drop a copy of the coffee addict SVG into the in subfolder within the svgopt project folder.

     
  2. 12.

    If all is well, we should see a new image show in the out folder within the svgopt folder – this one will be around 6KB smaller in size.

     

Phew – we’ve covered a few steps but now have a working optimization process in place! We’ve only touched the surface of what is possible, so let’s take a few minutes to review what we’ve created, to learn how we can tweak it for better performance.

Exploring the Demo in More Detail

Although it may feel like our demo required a lot of installation work, in reality much of this may already exist in your environment, particularly if you already use Node.js (or something that serves a similar purpose).

The real magic happens in the Gruntfile.js file – if we take a look at it, we can break it down into three sections: the initial configuration, loading the relevant tasks, and initiating the watcher task when we start Grunt at the command line.

The first section configures the svgmin plug-in – in this example we’ve configured it to keep the viewBox but remove redundant strokes and fills, and empty attributes. We’ve set it to pick up any SVG dropped into the in folder and drop it into the out folder with the .min.svg extension.

To facilitate the automation, we’re using the grunt-watcher plug-in in the watcher task – we’ve set some options to record the time and show a prompt when waiting for new images. The task is set to only run when adding new images or changing existing ones; this is to stop it running when images are deleted. As soon as it detects a valid change, the task fires off the svgmin task to complete the optimization process.

It’s worth noting that the configuration we’ve used is just an example – I would recommend adapting it to match the settings you find most effective, from the “Optimizing Manually” demo earlier in this chapter. A list of settings (and what they do) is available as a PDF in the code download; look for “SVGO Properties” within the Chapter 7 folder.

Okay – let’s change tack: we’ve learned how to optimize our content both manually and through the use of a task runner; there are still changes we may be able to make to improve our content. A key part of the process is to run a final check to see if we can make any final changes – let’s take a look at micro-optimizing our content in more detail.

Learning How to Micro-optimize Content

Although we’ve put our SVGs through an optimizer (you did do that, I hope?), there are always occasions where optimizers may not be able to fine-tune an SVG as much as we would like. It might be down to design, or that an optimizer simply doesn’t have that capability built in – we might not be able to change that, but we can at least perform a final check to see if there are any more changes that can be made to our code.

Unfortunately, this does mean getting down and dirty with our code – to help with this, there are a few candidates that can be checked:
  • If your image contains elements that are hidden (or perhaps too small to be viewed easily), then consider simply removing them – this will help reduce file sizes, remove unnecessary code and make it easier to manage the SVG.

  • If your SVG has some inline styles (such as fill), then consider moving them to a style sheet: this will help keep our code cleaner and be more intuitive. It may not suit all circumstances, such as designing a corporate logo that must retain the right colors and dimensions.

  • There is an argument for removing width and height values, if you are already using CSS; the latter will by default override the former.

  • Check the viewBox values – is yours set with a high level of decimal precision? We touched on this back in Assessing performance – the higher the precision, the larger the file size. The trick is to strike a balance between precision and visual fidelity, so that we don’t break our image by specifying too low a level of precision. Consider this extract:
    viewBox="-351.7474061, 2051.85204372, 2520.3925946, 2520.13473217"
    It’s very possible that we can reduce it by using a couple of simple tricks: repositioning our SVG and viewBox to use 0,0 as starting coordinates, setting whole integers rather than decimal places, and scaling down the original image. The resulting file size will be smaller, but without any loss of fidelity to the image – we can end up with a viewBox nearer this size:
    viewBox="0, 0, 252, 252"
At the same time, we should check through our SVGs to see what has been removed by our optimizer tool – at least for the first few images. If it hasn’t been configured to its optimal best, then we may miss opportunities for improvement:
  • Unnecessary attributes on the SVG element – many of the properties shown in Table 7-1 are frequently ignored or surplus to requirements; they can be removed if our optimizer tool has not already removed them.

Table 7-1

Redundant SVG Properties

Redundant Property

Explanation

X,Y attributes

These are coordinates for the top left position of the image – in many cases, they can be set to 0,0 or be removed from an individual SVG.

version="1.1"

Although it may be needed to comply with standards, just about every browser will ignore this value, so it can be removed.

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

This is only needed for external files; if your SVG is inline, it can be safely removed.

id="layer"

ID values represent the layer of the image – if you are not making use of it when styling, it can be removed; note though that the layer will disappear if you subsequently edit it in an application such as Illustrator or Vectr.

xmlns:xlink=" https://www.w3.org/1999/xlink "

If this isn’t being used, then it is safe to remove. If you are unsure, try removing it, and monitoring for any adverse effects.

style="enable-background"

This property is meant to help make the background available to child elements; it’s useful for filter effects. It was deprecated in 2014, so can be safely removed from those SVGs that may still have it.

Width / Height

These attributes control the dimensions of the image – these can be removed if you are using CSS-based styling.

xml:space="preserve"

This has officially been removed from Web standards, so it can be removed from code if it is still present.

  • The XML doctype and comments aren’t needed: as the image will inherit the doctype from the parent, so both can be removed.

  • Remove groups where possible – they are useful when creating SVGs, but if you don’t have multiple images in the same SVG (particularly when animating content), then they can be removed. Bear in mind though, that if an image has a lot of elements, then I would consider using groups for ease of readability.

  • Remove any whitespace from new lines, tabs, and indents.

It’s important to stress that many of the settings shown in Table 7-1 should already be removed automatically by an optimizer tool. I would recommend getting to know what these values are, so that you can either remove them manually when needed or alter them in the event your tool is not available.

There is one further place where we can optimize our content, which we’ve not covered in detail thus far: data URIs. At face value, you might not expect to be able to make any improvements, but remember us talking about them back in Chapter 3? Well, there is always room for improvement, so time we revisited these, to see how optimizing them can reduce the page weight and subsequent file sizes.

Paying Attention to Data URIs

Cast your mind back to Chapter 3 if you will – in particular to the section marked “Working with Images and Typography.” Yes, I know it may seem like a long time ago, but there is a reason for this, so let me explain.

We touched on several different formats of data URIs and created a simple demo that showed how we can display an image using four different data-URI formats, to learn which is the most efficient. Clearly the base-64 format came out worst (which you may or may not expect); the most effective solution was to use the native SVG format, with only a moderate increase in size when fully optimized.

Why is this important? Well, the simple answer is that it’s another area where we can optimize our code. Many of the standard SVG optimizers are not likely to include this level of fine-tuning, so we need to allow for it in the overall optimization process if we don’t want to miss out on an opportunity. It may not seem like we save many bytes with each image, but over time this will all add up – it’s important to focus on the bigger picture, and not just the individual savings we get from each image.

The developer Chris Coyier has a great article on the finer points of optimizing dat-uris, which is available at https://css-tricks.com/probably-dont-base64-svg/

Okay – enough chit-chat: let’s get active! For our next exercise we’re going to set up a simple demo to automate the optimization of an SVG image. For the purposes of this demo we’ll use the same coffee addict image we’ve already used before; if you want to use a different image, then please adjust the steps accordingly.

Optimizing Data URIs

For our next exercise, we’ll make use of the mini-svg-data-uri plug-in, available from https://github.com/tigt/mini-svg-data-uri . Created by the Ohio-based developer, Taylor Hunt, this plug-in encodes standard SVG files for use as data-URIs; they can then be specified as images within a project’s style sheet. For the purposes of this demo, we will assume that Node.js is already installed and ready for use, and that we will use an (optimized and renamed) copy of the coffee addict image from earlier demos.

OPTIMIZING DATA URIS

Let’s make a start with setting up our script:
  1. 1.

    We’ll start by extracting a copy of the datauri folder from the code download that accompanies this book – save it at the root of our project folder. This contains our script and example image, all ready for use.

     
  2. 2.

    Next, go ahead and fire up Node.js command prompt (or terminal session, for Mac users) as administrator, then change the working folder to datauri, and run this command at the prompt: npm install mini-svg-data-uri --save-dev

     
  3. 3.
    We now need to set up the script that will convert our SVG image into something that can be used as a background image. Go ahead and paste the following code into a file, saving it as datauri.js in the datauri folder:
    var fs = require('fs');
    var svgToMiniDataURI = require('mini-svg-data-uri');
    fs.readFile('in/coffee.svg', 'utf8', function(err, data) {
      if (err) throw err;
      var optimizedSVGDataURI = svgToMiniDataURI(data.toString());
      console.log(optimizedSVGDataURI);
      fs.writeFile("out/coffee.min.svg", optimizedSVGDataURI, function(err) {
        if(err) { return console.log(err); }
        console.log(" The file was saved!");
      });
    });
     
  4. 4.

    Switch back to the command prompt (or terminal session), then run node datauri.js and press Enter. We should see something akin to the image shown in Figure 7-10.

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig10_HTML.jpg
Figure 7-10

Our converted SVG as a data-uri

It’s worth noting that the contents of console log will have been saved to disk – in this case, as coffee.min.svg. The file itself will not be viewable by itself (if you try to open in a browser, for example), but it is designed to save a copy of the data URI, so it can be incorporated into our CSS style sheet at a later date.

Although we’ve kept our script short and simple, there are a number of improvements we could make – let’s first take a look at the code in more detail.

Exploring the Code in Detail

We begin by linking to Node.js’ File System module, before reading in the contents of the coffee.svg file and assigning to a storage value named data. We then run it through the svgToMiniDataURI module , which converts it to a data URI, before rendering it onscreen (console). The contents of data are then saved to disk as coffee.min.svg, so that we can then use the data URI in our code at a later date.

At this point, let’s step back for a moment: going to all of this effort to add what seems to be just a few extra characters might not feel right; after all, why not just use a standard base-64 conversion as the source for our background-image statement?

It’s a valid question – to really understand the benefit we get from this process, let’s strip it back to a simpler example and run some comparisons with a smaller SVG. For the purposes of this demo, I’ll use an icon from the Open Iconic project that we made use of earlier, hosted at https://useiconic.com/open :

COMPARING DATA-URI VALUES

For this exercise we’ll use the SVG code for the align-center icon – you can of course use any icon for this, as long as it the SVG code is simple:
  1. 1.

    We’ll begin by browsing to https://npm.runkit.com/mini-svg-data-uri  – this allows us to run the mini-svg-data-uri plug-in, in an online environment that is already set up to run this plug-in.

     
  2. 2.
    Go ahead and add the following code into the code box on the left side of the page, replacing what is already there – the code box is immediately below the words “…Try it out”:
    var svgToMiniDataURI = require('mini-svg-data-uri');
    var svg = '<svg xmlns:="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8"><path d="M3 0v1h4v5h-4v1h5v-7h-5zm1 2v1h-4v1h4v1l2-1.5-2-1.5z" /></svg>';
    var optimizedSVGDataURI = svgToMiniDataURI(svg);
     
  3. 3.

    Click on the Run button to the bottom right of this code box, then select Full Text from the drop-down, a little to the left; if all is well, you will see the code shown in Figure 7-11:

     
../images/461821_1_En_7_Chapter/461821_1_En_7_Fig11_HTML.jpg
Figure 7-11

The results of running our data-uri plug-in

This seems straightforward enough, right? Let’s compare the results of our change, against other data-URI formats. First up is the original, unaltered SVG code:
<svg xmlns:="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8"><path d="M3 0v1h4v5h-4v1h5v-7h-5zm1 2v1h-4v1h4v1l2-1.5-2-1.5z" /></svg>
This weighs in at 150 characters, including spaces. In comparison, here’s the resulting code after we’ve run it through the optimization process:
data:image/svg+xml,%3csvg xmlns:='http://www.w3.org/2000/svg' width="8" height="8" viewBox='0 0 8 8'%3e%3cpath d='M3 0v1h4v5h-4v1h5v-7h-5zm1 2v1h-4v1h4v1l2-1.5-2-1.5z' /%3e%3c/svg%3e
This weighs in at 181 characters, which is an increase of 31 characters, or just under 21% of the original value. Now compare that with a standard base-64 conversion – we can already see a bigger increase in code:
PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4IiBoZWlnaHQ9IjgiIHZpZXdCb3g9IjAgMCA4IDgiPjxwYXRoIGQ9Ik0zIDB2MWg0djVoLTR2MWg1di03aC01em0xIDJ2MWgtNHYxaDR2MWwyLTEuNS0yLTEuNXoiIC8+PC9zdmc+

This weighs in at 200 characters, which is a 33% increase on the original code – clearly not so good! Granted, there will always need to be an increase in code to allow for any conversion, but it’s clear to see that base-64 conversions aren’t as efficient as simply encoding our SVG using the plug-in.

Leaving conversion theory aside for a moment, and thinking further afield, how could we improve on our code? Well, as a starter for 10 – how about making it dynamic, then integrating it with a watch task, so it performs this change for any image dropped into an inbox folder automatically? We’ve created the background-image URL code, so how about creating the CSS rule to suit? These are just two of the ideas that come to mind – it’s really up to us to decide how far we take it, to provide the most effective solution for our project needs.

Summary

When working with SVGs, optimizing our code is just as important a process as creating content. If done with care, it can make a real impact on the size of our files, help reduce bandwidth usage, and ultimately lead to a faster experience for our customers. We’ve covered a number of useful tips to help with this process, so let’s take a moment to review what we’ve learned.

We kicked off with a brief overview of the best way to export images, before moving swiftly on to explore why optimization is important and taking a look at some of the areas we should target for improvement.

Next up came a quick look at how we can maintain accessibility as part of this process, before learning how to shrink our images using the SVGO tools. We then moved onto covering how we can micro-optimize our content further, to alter or remove code those other optimizers can’t reach, before finally working on how we can improve data-URIs that frequently need more special attention.

Phew – another monster chapter bites the dust, to (mis-) quote the words from that famous song! Still, our journey continues apace; over the course of the next three chapters we will take a look at some example uses of SVG, kicking off with a dive-in to creating interactive charts.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.60.62