Three small tips for shrinking SVG images

by @edent | # # # # # # | 6 comments | Read ~661 times.

I work on the SuperTinyIcons project. Our aim is to make pixel perfect SVG icons in under 1KB. Because SVG can be quite verbose, every single redundant byte we can eliminate is a byte we can use in drawing.

Here are three quick tips for shaving a few bytes off an SVG.

Decimal Magic

SVG co-ordinates can have decimal precision, like: 123.456. But what about co-ordinates which are less than one? 0.123 can be rewritten as .123 – we can drop the 0!

These two sed commands will turn 0. to . and -0. to -.

sed -i -z "s/ 0\./ \./g" *.svg
sed -i -z "s/\-0\./\-\./g" *.svg

What’s my (new) line?

For boring technical reasons to do with teletype printers, Windows machines use two characters to represent a newline. CR the Carriage Return send the print-head back to the start of the line, then LF is the Line Feed to move the paper by one line.

Unix just uses LF. Because no-one uses teletypes.

The brilliant dos2unix program will convert all Windows-style newlines to Unix style. Magic!

Last Line

Most text editors add a newline to the end of any file you create. Why? Who knows.

Remove any trailing newlines from the file with:

sed -i -z s/\\n$// *.svg

Using the above three commands, I’ve been able to shave off dozens of bytes from these files. A worthy endeavour, I’m sure you’ll agree!

If you want to make images as small as humanly possible, come join us.

6 thoughts on “Three small tips for shrinking SVG images

  1. SuperTinyIcons needs its own logo!


  2. Chris Midgley says:

    Most text editors add a newline to the end of any file you create. Why? Who knows.

    It’s a POSIX standard. Having files end with newlines makes them work better with certain Unix tools, such as cat. Why text editors have adopted this standard is a different question — I’d understand why the old Unix ones would, but not the newer or Windows ones.

  3. I love me a good byte pinching.

    Have you considered increasing viewport sizing to remove decimal points?
    If a design requires 2 decimal precision then increasing the viewport sizing by a factor of 100 will save another byte per number used.

    How about using easily dividable viewport sizes?
    Using viewport=”0 0 960 960″ is dividable by more integers, producing integers, than say a “0 0 1000 1000”.

    1. @edent says:

      That’s a good point. I made the rather arbitrary to go for a viewport of 512×512. Some of the icons use a different size and then transform. See https://edent.github.io/SuperTinyIcons/images/svg/linux.svg

      <svg xmlns="http://www.w3.org/2000/svg"
      aria-label="Linux" role="img"
      viewBox="0 0 512 512" fill="#333"><rect
      width="512" height="512"
      rx="15%"
      fill="#fff"/>
      <g transform="matrix(2 0 0 2 256 256)">
         <path d="M-32-25c-3 7-24 29-22 51 8 92 36 30 78 53 0 0 75-42 15-110-17-24-2-43-13-59s-30-17-44-2 6 37-14 67"/>
         <path d="M42 21s9-18-8-31c16 17 6 32 6 32h-3C36-13 27 6 14-56 29-73 0-88 0-60h-9c1-24-20-12-8 5-1 37-23 52-23 78-7-18 6-32 6-32s-18 15-7 37 31 17 17 27c22 15 56 5 55-27 1-8 22-5 24-3s-3-4-13-4m-56-78c-7-2-5-11-2-11s8 7 2 11m19 1c-5-7-1-14 4-13s5 13-4 13" fill="#eee"/>
         <g fill="#fc2" stroke="#333" stroke-width="1">
            <path d="M-41 31l21 30c11 7 5 35-25 21-17-5-31-4-33-13s4-10 3-14c-4-22 14-11 19-22s5-16 15-2M71 45c-4-6 0-17-14-16-6 12-23 24-24 0-10 0-3 24-7 35-9 27 17 29 28 16l26-18c2-3 5-6-9-17m-92-92c-3-6 11-14 16-14s12 4 19 6 4 9 2 10S3-35-5-35s-10-8-16-12"/><path d="M-21-48c8 6 17 11 35-3"/>
         </g>
         <path d="M-10-54c-2 0 1-2 2-1m7 1c1-1-1-2-3-1"/>
      </g>
      </svg>
      

      If you think a 960 viewport would be better, please propose the change!

      1. I tried to replicate linux.svg in both 960 and 360 viewports.
        In this specific case, the points all fall easily inside 512, so there’s no advantage increasing to 960.
        So, I tried using 360 and came within 10 bytes ish of your result, with the transform removed.

        If I was starting a new SVG, I’d advise using either 960, 360, or 60 dependant upon the complexity (or the accuracy required to remove decimal places).
        Other multiples of 60 are equally usable.
        The reasoning: At lower multiples, base 60 numbers have more natural divisors (1, 2, 3, 4, 5, 6, 8, 9, 10, 12) than binary, hexadecimal, or decimal.
        Caveat: This doesn’t mean better results cannot be attained using specific viewports, though it should prove a better start point generically.

Leave a Reply

Your email address will not be published. Required fields are marked *