Google posted Guetzli last month. Curious about testing it out, I decided it to give it a go. Image optimization is one of the bazillion things a front end developer needs to know something about. For the sake of sanity, I'm going to assume that readers understand that PNGs are lossless and JPGs are lossy. However, most programs that encode to file formats often include additional metadata, or do not make the most efficient usage of the codec thus not all encoders are created equally. Perceptual encoding is tricky and thus assumptions are made within the constraints of the codec as how to interpret the input data. Based on this, there's generally wiggle room to improve encoders to make them "smarter" and deliver better results.
Optimization doesn't end at the encoder. In the interest of delivering the smallest file possible, people have written many series of optimizations designed for existing JPEGs and PNGs. The easiest (and incidentally one of the most effective) is ImageOptim. Without going too deep, ImageOptim combines several popular image optimizations specific to both JPEGs and PNGs and makes it into brain dead easy optimization. It shaves off valuable kilobytes without affecting the image quality. Usually, I export assets from Photoshop or Sketch then treat them with ImageOptim and ImageAlpha (for PNGs). Often front end developers will use Grunt and Gulp tasks that use many of the same libraries that ImageOptim uses to auto-optimize images in a project. Google's Guetzli is a new JPEG encoder which offers new opportunities over my usual post-export optimization tweaks. Guetzli promises better results as opposed to simply smaller files.
I downloaded guetzli using the HomeBrew version for OS X/macOS. For my test, I started with high fidelity non-lossy images thus used images captured in RAW and converted to PNG source files.
Rather than inline my source images, here are the below links for reference and the relative time it took to encode on my MacBook Pro 2016 2.5 GHz Intel Core i7, 16 GB RAM, at 84 quality as defined by Guetzli.
- Guetzli Test Image 1 (19 MB) - roughly 16 minutes, Result 1.7 MB, Compare against Photoshop (6 out of 12 quality) at 1.1 MB
- Guetzli Test Image 2 (2 MB) - roughly 2 minutes, Result 223KB, Compare against Photoshop (6 out of 12 quality) at 236K
Apples and Oranges
The big problem is that Photoshop uses a 0-12 quality setting which has never been very sensible. Unlike video codecs that allow you specify to target file sizes via bit rates, there's no real way to produce file sizes at the same size a Guetzli's JPEG engine. Instead it was a guess work, trying to figure out what Photoshop quality produced nearish the same file sizes. After testing several images, Photoshop's 6 out of 12 was the most "like" setting and its highly imperfect. For my very large image, the Photoshop 6 out of 12 quality JPEG was much smaller than the Guetzli's minimum 84 setting. However, when images were much smaller, all other tests found Guetzli's 84 quality setting producing smaller files than Photoshop's 6 out of 12 quality setting. All images were also run through ImageOptim for further optimization.
Guetzli just isn't that effective on high resolution images and at least with my test source, the differences were not very profound. I debated running Guetzli on several 16 MP images but with 16 minutes per-convert, the practical application isn't there for most use cases. This had me go back to the drawing board so I downscaled my image to represent a more likely scenerio.
Zoomed In Test
The following images are screen captures of the zoomed in results of the PNGs/JPGs for comparison. Linked next to each image is the original image (prior to zooming in). Right click to open up the zoomed images for full sized images. My two main test images are both images that have large gradients which JPG artifacting often is the most visible.
Original PNG (size 1.2MB)
Photoshop JPG (size 95k)
Guetzli JPG (size 88k)
Surprisingly, Guetzli doesn't come out ahead. You can see the gradient blockiness in Guetzli's JPG. It's more apparent viewing this on a non-Retina display or at 2x on a retina display. The JPEG blur of the default Photoshop image works to its advantage on the gradients. I certainly didn't expect Photoshop's JPEG engine to win any test. That said, the Guetzli image is 7k smaller.
Original PNG (size 2MB)
Photoshop JPG (size 236k)
Guetzli JPG ( size 223k)
Guetzli comes out ahead quite a bit in the detail of the sky, something JPGs tend foul up quite a bit. Guetzli certainly wins in this instance and looks better than the Photoshop image.
Guetzli is slooooooooooooooooooooow. Converting a 20 mb PNG (4,608 x 3,456) image under a normal load (a few applications open, Atom, Preview, Messages, Safari, Chrome, iTunes, Sketch, Codekit, textedit, 1password, Lightroom, Tower), cost roughly 16 minutes of CPU time on a 2015 MacBook Pro (2.5 GHz i7 / 16 GB Ram). First off Guetzli is a single thread application, occupying 99-100% of the 4 cores on my CPU. Sadly, it left 80% of my MacBook idling. Optimization for OS X is nearly non-existent.
Guetzli is designed for high quality JPGs, by default the quality slider is limited to 84. Anything else will throw up an error in the CLI. It is possible to bypass this by building the binary yourself. Guetzli also is designed to delver higher quality at the same file size than a JPEG encoded by lesser image, as opposed to simply produce smaller JPGs.
Guetzli assumes the color profile for the JPEGs is SRGB with a Gamma profile of 2.2, this is the same as the default for Adobe RGB (1998) buuuut not as wide of a color space as it'll read as an untagged image color profile. Thus images you've been viewing in Adobe RGB may end up looking less saturated or vibrant.
For static assets that rarely change, Guetzli is certainly an option but for my Front End flow, it's not going to be anything I lean on. There's certainly been some impressive image optimization utilities for JPEG over the past several years but my guess we're coming up against the limitations of JPEG. The sadistic side of me wonders if it could be used for Motion JPEG, which is eschews interframes/keyframes.