How Nano Compresses SVG
May 08, 2018 · Thomas Yip · Everything SVG · Compressing SVG
Wanted to know how Nano compresses SVG? Of course you do, so let's have a look at the long list of techniques we used to compress your SVG.
Please do note that these techniques are not exhaustive, and we will further improve nano with more techniques to ensure even smaller sizes.
The entire SVG will be scanned for used text elements. If none is used, no fonts will be embedded. If text are used, only used fonts are embedded, to ensure smallest of file size.
Removing tabs, line feeds and carriage returns
Whitespace characters such as tabs and carriage returns are redundant in SVG and can be safely removed.
Remove events and scripts
SVG files are allowed to have scripts and events according to specifications. However, for the case of using an SVG on an
<image> tag, no external resources, scripts nor events are allowed, therefore it can be removed. For usage on
<object> tags, they are preserved.
<!-- Some svg comments --> <svg width="10" height="10"></svg>
Comments in SVG can be safely removed.
Remove namespaced tags
SVG codes produced by some editors may contain namespaced tags:
<inkscape:perspective inkscape:persp3d-origin="0.5 : 0.33333333 : 1" id="perspective2824" />
For use cases such as embedding svg images on websites, these namespaced tags can be safely removed without affecting display.
Remove namespaced attributes
<rect v:begin="thin.end" />
Namespaced attributes are used by editors to store data and can be safely removed.
Remove third party namespaces
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:v="http://vecta.io">
Many editors including vecta.io insert a namespace and these can be safely removed.
Removing unused ID and classes
<g id="jgqbvghln5" transform="translate(20 10)"> <rect width="10" height="10" x="0" y="0" /> </g>
Most editors insert an ID into every element to keep track of them. These IDs, if not referred by another element, can be safely removed. If a class is defined in a style, and it is not used on any elements, they will be removed.
<g id="jgqbvghln5" transform="translate(20 10)"> <rect width="10" height="10" x="0" y="0" /> </g> <!-- will be compacted to: --> <g id="A" transform="translate(20 10)"> <rect width="10" height="10" x="0" y="0" /> </g>
If an ID is used, nano will compact the ID into a very short string to save space. The same applies for classes.
Removing hidden elements
Elements with opacity === 0, width === 0, display === none, etc, will be removed because they do not render.
Polygons, polyline and line elements will be converted to paths, because paths occupies less space. If a rectangle does not have rounded corners it will also be converted to paths. If an ellipse have the same x and y radius, it will be converted into a circle.
Removing zero units
By default, certain SVG elements will have 0 as default, therefore specifying x="0" for a rectangle is not necessary and can be safely removed. Nano selectively scans the entire SVG to remove these unnecessary attributes.
<style> tags and in attributes will be minified, respecting CSS styling precedence and specificity. Unused styles or CSS rules that does not affect any elements will be removed.
Removing unknown or extraneous attributes
The SVG specifications are very clear on what attributes are allowed on elements, therefore unknown or extraneous attributes will be removed. For example, stroke-linejoin and stroke-linecap attributes will be removed from circle elements because these attributes does not affect the rendering of the circle element.
Nano scans the entire SVG to reduce colors into the smallest string. If a hex 6 color is encountered (#000000), it will be replaced with #000. Whenever possible, predefined SVG colors will be used, only if they are shorter in length.
Removing title and description
For the use case of embedding SVG with
<img> tags, title and descriptions can be safely removed, for they will not display, and will only be useful when embedding with inline SVG.
Removing useless containers
<defs> <defs> <rect id="A" width="10" height="10" /> </defs> </defs> <!-- will be minified to: --> <defs> <rect id="A" width="10" height="10" /> </defs>
Although the SVG specification allows container elements to contain other container elements, these are not necessary and can be safely removed without affect SVG display.
Compressing transform attributes
Whenever possible, transformations will be applied to elements, including gradient elements without affecting rendering, to save space. Complex, multi step transformations will be simplified into a single transformation.
Merging and minifying paths
If paths does not intersect and are not styled with gradients, they can be safely merged to result in space savings. Path attributes are also minified when possible, to result in the shortest "d" attribute.
Removing useless groups
<g><rect width="10" height="10" /></g> <!-- will be reduced to: --> <rect width="10" height="10" />
Useless groups will be removed or reduced whenever possible.
Whenever possible, values will be rounded to 3 decimals, so attributes with 2.0000009, will be selectively and smartly rounded to just 2.
Founder at vecta.io, created Capital Electra, engineering nerd.