clicktorelease

Hi! My name is Jaume Sanchez!
I like to do things with the browser
(NOT those kind of things, you pervert!)

Find me on twitter or GitHub

Can the new Google logo be 305 bytes?

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.

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.

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

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.

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 toxis 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.

<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.

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

Removing the xmlns attribute forces the X default.

<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.

<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.

<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.

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

<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"".

<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.

<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

<svg width="600" height="300">
<svg viewbox="0 0 600 300">
<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!

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:

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.