GIFs are funny.
Take a look at the following beautiful gradients in GIF format:
The vertical GIF gradient weighs in at 12.6KB, whilst the horizontal GIF gradient weighs in at 63.9KB. (I have wpsmush running on here, but those are the sizes pre-upload. The larger image lost 2.08KB, whilst the smaller lost 37B).
Why is this the case?
“GIFs follow a compression algorithm that removes horizontal redundancy. So by introducing extra vertical details or noise, we’ve increased the file size of the GIF.” – Lara Callender Hogan
These images are dramatically different sizes because the GIF format offers significantly better compression in one direction.
So what if we were committed to displaying horizontal GIF based gradients, but wanted the performance of vertical GIF based gradients?
We’re in real hypothetical territory here, and I’m a big fan of the terrible bodge:
<img src="horizontal.gif" style="transform: rotate(90deg);"/>
And this bodge removes 80.28% of the filesize.
To put it another way – You can (possibly) reduce page weight by saving a copy of a GIF rotated 90 degrees, and rotating it back with CSS.
Real World Example
The following space-jump GIF is 889.85KB:
While saved at a 90 degree rotation this same GIF is 809.72KB:
<img src="horizontal.gif "style="transform: rotate(270deg);"/>
This took the article from a whopping 19.3MB to a svelte 18.7MB. Picking the winners from these lists doesn’t get us down further. Not big money to us, but not a saving for Buzzfeed or Giphy to sneer at either.
Running With This
To apply this at some scale we could start with the following.
- Batch Convert GIFS.
- Test for size.
- Upload smallest of each pair.
- Handle your now ruined CSS.
You can use a processor like imagemagick to create rotated copies of your .gif images:
convert example.gif -rotate 90 example_90deg.gif
Then, perform a test to compare the original gifs and their rotated versions pairwise. We want to work with the smaller file of the two.
Now, if the src attribute of an <img> tag ends with ‘_90deg.gif‘ (or similar), we’ll want to rotate it back to ‘normal’. We can do that with the following rule:
-webkit-transform: rotate(270deg); -moz-transform: rotate(270deg); -o-transform: rotate(270deg); -ms-transform: rotate(270deg); transform: rotate(270deg);}
Upload these files and ensure your HTML is pointing to the the correct rotated versions. This will certainly play havoc with your current CSS setup, especially with specified image dimensions.
It’s all good saving a few bytes on the upload, but what if it’s at the expense of battery life and render time? Every site is different, and this is too fiddly a method to be of actual use, but I’d love to hear your thoughts. I don’t believe 2D transformations are slow or resource heavy, so the tradeoff there is probably sound.
Although layout is more or less done before the images load in, I must admit that it looks really weird watching images load from left to right, rather than top to bottom.
If your website purely deals in non-animated GIF based gradients (which it shouldn’t), then I’d strongly recommend adopting this method!
This idea popped into my head a while after reading Designing For Performance. Excellent book!