Optimizing Images - Part 2
This is the second part of the Optimizing Images series. In the first article we talked about the basic concepts and techniques to optimize raster images, and today we’ll talk about techniques to optimize SVG files.
SVG File Content
Unlike raster images where the content is the information for the color of each pixel of the image, SVG files are in essense just text files with XML content describing shapes, functions and attributes to tell the computer what to draw. Instead of reading data, the application drawing an SVG file into the screen must first calculate what to draw on the screen.
A really basic example of an SVG file is this:
<svg height="100" width="100"> <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" /> Sorry, your browser does not support inline SVG. </svg>
Because the file does not contain data of only one predefined image size (the values in the previous SVG file are not pixels!), this means the image can be scaled to any size we want and it will always have good quality.
Using SVG Files
img tag allows a source of type SVG. The intrinsic dimensions of the image will be based on the SVG’s viewport size (the attributes of the
svg tag) if unspecified, similar to how raster images work. The advantage of this approach is that it provides consistency with the rest of the images using the same HTML tag, and allows us to use it inside a
picture element’s source set to provide different SVG versions for different sizes.
This method has 2 main disadvantages (compared to inline
- We can’t apply CSS styles to the content (we can only apply style to the
- Like any image
src, it requires an extra HTTP request to fetch the
Similar to this, SVG files can be used as background images in CSS pointing to a
.svgfile url, with the same disadvantages.
Another option we have is to use the content of an SVG file directly in our HTML since the
<svg> tag is a valid HTML tag. Again, the default size will be based on the viewport size and scaling it will keep the quality. Compared with the image
src usage, we can’t use inline SVG files inside a
The main advantages of using this method are:
- Avoid extra requests (since the
svgcontent is shipped with the HTML of the page in the initial request)
- The ability to style not only the parent
svgtag but also any element in its content (which provides a lot of flexibility)
We can use the
inline_svg gem to be able to easily inline SVG files from our assets folder. This gem also allows caching the SVG content in memory to not have to read the
.svg files every time it needs to render them, improving the response time of the request.
Which Method Should We Use?
You guessed it… it depends!. Inlining the SVG images will reduce the number of HTTP requests done when the page loads but, if the page includes too many, it can increase the size of the initial response (though it would have to be really TOO MANY).
As a rule of thumb, inlining SVG files tends to improve the load speed of the app but you should try both and compare (and in some cases you may want to mix the methods in different places).
Not all the content of an SVG file is important for a computer to draw it. We have XML comments, new lines, white spaces, metadata, etc. Similar to how we can minify CSS and JS files to make them smaller, we can minify and remove unnecessary content to shrink our
.svg files. This benefits both usage methods, either including less code in the response or sending smaller files to be used as image source.
CSS-Tricks provides a lot of options to do this task, check them here.
My personal recommendation is https://jakearchibald.github.io/svgomg/
Raster In SVG
The SVG format allows adding
image tags inside it (not to be confused with HTML’s
img tags) to include raster images inside the SVG’s content. Content can be a link to an external resource or base64-encoded bitmap data.
This is not always recommended, especially if the raster image is big, since it will defeat the purpose of vector graphics that are intended to be light. Since there are valid reasons to have this inside an SVG file, each case needs to be analyzed to see if it can be simplified or if the raster image is really needed.
While SVG files and both methods of using it are supported in all browsers, in our experience it’s important to still test in different browsers, since we are not sending the result of the image but the instructions to generate it and browsers may not always work exactly the same - I know, not really suprising. For example, we have noticed blurred icons on iOS devices when the SVG file includes the
mask tag. To workaround that, we had to fall back to PNG files.
Inlining and minifying SVG files can reduce the number of external requests considerably (in an application with many images and icons, this could mean tens of requests avoided!) and, at the same time, allow extra customization with CSS styles that is not possible with
img tags and would require more variants of a file to achieve.
This might not always be the best solution but, in our experience, this provides good optimization more often than not.
Is your application feeling slow? Contact us to get a Tune Report performance audit of your complete application stack.