ArticlePosted on August 2015

Can the new Google logo be 305 bytes?

Reading time: 10 minutes

Topics: SVG, Code golfing

This is a legacy post, ported from the old system:
Images might be too low quality, code might be outdated, and some links might not work.

In this post I'll talk a bit about techniques and tricks learned while trying to recreate the new Google logo with SVG in 305 bytes (or less!). Martin Kleppe has helped me reviewing the post and contributing with many juicy bits!

Why 305 bytes?

A few weeks ago (beginning September 2015) Google unveiled their new identity, complete with a nice article covering the evolution of the logo.

One of the points the article made about distribution was:

This helps us make the design pixel perfect everywhere it’s used, and it allows us to optimize these assets for size and latency, including building a special variant of our full-color logo that is only 305 bytes, compared to our existing logo at ~14,000 bytes.

That was intriguing: there are many well-known techniques to make assets lightweight, but 305 bytes sounded too few to me.

Google has a new logo. The smallest version of it is a 305 byte SVG file. #perfmatters https://t.co/zpR5imrznf pic.twitter.com/ymTSiiFpJH

— Addy Osmani (@addyosmani) September 1, 2015

Addy Osmani had mentioned that the small logo was SVG, and actually many people were wondering if it was somewhere online to take a look. I thought it should be simple enough to try to write an SVG and check the size of the resulting file. The idea wasn't to replicate the logo pixel by pixel, but to check if, having the right elements in the file, how close the size can get to 305 bytes.

Building the logo

Looking at the logo, it looks like it's not composed of filled-in shapes, but rather a few shapes, drawn with a thick stroke: that is, a rectangle is not a polygon made of four coordinates filled in with colour, but a thick line connecting two points.

I opened the biggest version of the new rasterised logo that I could find, and I start using OSX's Command + Shift + 4 screenshot tool to get measures on screen. I was compressing the file manually on disk to check the compression.

I got Goo and the file was already 304 bytes. Not looking good.

@jedschmidt @aemkei @p01 @addyosmani damn... i've got "goo" and i'm already in 304 bytes :| pic.twitter.com/QmHbu8nN7W

— Jaume Sanchez Elias (@thespite) September 2, 2015

I then started using SVGOMG (Jake Archibald's GUI for SVGO) and the size promisingly went down. I was at Googl at 265 bytes.

@jedschmidt @aemkei @p01 @addyosmani 265 bytes -even though the paths are a bit wonky, i'm eyeballing them pic.twitter.com/xbQSvVOqaA

— Jaume Sanchez Elias (@thespite) September 2, 2015

The final version -or so I thought!- was complete, with the lowercase g composed of three paths. There's some discussion regarding this, but I think the geometry of that letter can only be done with two arcs of different curvature for the body, plus another arc for the descendent. A circle (like the o letters) is not the same shape.

Can the new google logo be 305 bytes? Sure! This is a quick and dirty version in 290 bytes http://t.co/YinwdHrfAD pic.twitter.com/WGCZqIZqA3

— Jaume Sanchez Elias (@thespite) September 2, 2015

Code golfing across time and space

After posting the final version, Martin Kleppe -code golfer extraordinaire- opened fire reducing 20 bytes (5 bytes gzipped) with several combined tricks.

One of them is removing the XML NameSpace attribute (xmlns="http://www.w3.org/2000/svg"). This has the side effect of turning the file unrenderable directly on a browser, since it's interpreted as an XML file without any style information, and the browser only shows the document tree. But JS Bin adds the right mime-type header to the file, so the browser correctly interpets it as an SVG file and renders its content. That also means that if not interpreted as the right type of resource, some XML parsers might throw errors (in browser and other tools and editors). Removing the XML NameSpace will also work, when inlining SVG tags in HTML.

We settled on JS Bin as a platform for ping-pong'ing the different iterations of the file. This turned out not to be a great idea, since jsbins created by unregistered accounts have an expiration date (I didn't know that at the time). Fortunately, I kept several intermediate steps.

Big kudos to Remy Sharp for creating and putting so much of his life in JS Bin. If you haven't read his series of posts "The toxic side of free", do it now; it's a very good read and lots of deep insight into side projects and coding.

To test the compressed size of the file we used checkgzipcompression.com, by providing the URL of the JS Bin.

Check the whole twitter timeline for details, but here's a list of techniques that were tried, and how successful they were:

Removing attributes

Some attributes can be removed without much effect.

Remove attributes that have no effect

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="600" height="300"></svg>

Removing the version implies version 1.0 by default.

Assume implicit version

<svg xmlns="http://www.w3.org/2000/svg" width="600" height="300"></svg>

Removing the xmlns attribute forces the X default.

Remove xmlns attribute

<svg width="600" height="300"></svg>

86 down to 37.

Ignoring spaces between attributes

When having attributes with quoted values you can skip the spaces, since the closing quote acts as separator.

A more complex SVG document

<svg width="600" height="300" stroke="#d83038" fill="none" stroke-width="16">
  <path stroke="#4ab95a" d="M449 51v115"/>
</svg>

Removing the spaces makes valid SVG, but a lot of syntax highlighters don't parse the code correctly, and some report errors.

Removing spaces between attributes

<svg width="600"height="300"stroke="#d83038"fill="none"stroke-width="16">
  <path stroke="#4ab95a"d="M449 51v115"/>
</svg>

124 bytes to 118.

Note that the technique in the next point makes this one obsolete, but sometimes you need to try different options, or mix them.

Removing all quotes

SVG admits attributes with and without quotes. That's a big win in size, since it removes two chars per attribute. Two things to consider: space separated values in attributes (such as d) can be unquoted by replacing spaces by commas; and when the attribute is at the end of the tag, leave a space before closing the tag.

Back to original SVG with spaces

<svg width="600" height="300" stroke="#d83038" fill="none" stroke-width="16">
  <path stroke="#4ab95a" d="M449 51v115"/>
</svg>

Removing quotes from all attributes

<svg width=600 height=300 stroke=#d83038 fill=none stroke-width=16>
  <path stroke=#4ab95a d=M449,51v115/>
</svg>

124 bytes to 109 bytes.

Grouping attributes

There's repeating colours in the logo: two letters are blue, two letters are red. You can choose one to be the default colour of all shapes, defined in the svg tag, and only change it in the path elements that have a different colour. At the same time, repeating patterns are good for compression (see next point), so this technique can shave some bytes, but may be the straightforward approach work better on the long run. In this case, we experimented with putting and taking attributes and some "forked" versions performed better regarding size.

This technique is worth considering nevertheless. The cascading nature of SVG attributes can save you lots of space if used wisely.

Ordering attributes and string

Compression algorithms look for repeating patterns that can be replaced by keys in a dictionary. Reordering text to make patterns emerge is a very good way of improving compressibility.

Unordered attributes

<circle cy="128" cx="227" r="32"/><circle stroke="#f4c022" cy="128" cx="313" r="32"/>

Repeating strings are circle, cy="128" and r="32".

Ordered attributes for better compression

<circle r="32" cy="128" cx="227"/><circle r="32" cy="128" cx="313" stroke="#f4c022"/>

Once sorted, the repeating string is circle r="32" cy="128". Same length, but it compresses better.

Ordered attributes and quotes removed

<circle r=32 cy=128 cx=227 /><circle r=32 cy=128 cx=313 stroke=#f4c022 />

And after applying the removal of quotes, the string is circle r=32 cy=128.

Replacing width & height by viewbox

Original SVG tag with width and height

<svg width="600" height="300">

SVG tag changed to viewbox

<svg viewbox="0 0 600 300">

Removed quotes with spaced replaced by colons

<svg viewbox=0,0,600,300 >

Dropping the viewbox was possible because the default SVG size is 300x150.

Using reusable SVG

Some people tried using advanced SVG syntax, like <use>, <def> and <symbol>. While these work great to get the original file size very small, the resulting text has too much entropy for the compression algorithms to be efficient. The result is a compressed file very similar in size to the original.

Our conclusion was that longer, more verbose SVG declarations used correctly were a gain when using gzip. But, as with other techniques, using reusable SVG syntax it might just work depending on your image.

Refactoring the SVG

Changing things around can also mean a big improvement. Replacing circle with path meant two big improvements: the GZIP compression kicked in harder, and several shapes with the same colour could be combined in the same path (both blue G's and the red o and e).

Big kudos to Mathieu 'p01' Henri, Felix Gnass and many others for their mastery refactoring and reducing the logo even further!

Thanks to @p01's path refactoring we can now drop the viewbox and golf the logo down to 265 bytes (152 gzip): http://t.co/xjPIv4cesi

— Felix Gnass (@fgnass) September 3, 2015

Visualise the compression

Martin used gzthermal ("pseudo thermal view of Gzip/Deflate compression efficiency") to optimize the order of some attributes.

This is some seriously cool tool!

Wrapping up

The last size was 146 bytes:

@aemkei @bisonfute @ChristopherBlum Almost boring at this point, but we're down to 146: http://t.co/jetPTdeMyP

— Wojciech Maj (@wojtekmaj91) September 10, 2015

It's amazing to think that it went down that much!

What we liked most was that at first we thought "is 305b possible?" and it ended up at 50% of that! It was a really fun process: trying, sharing and learning using local tools and the web.

I hope this has been interesting. If you've found something out that didn't know before, mission accomplished! As always, comment on the section below, or hit me on twitter or e-mail.

Comments