Andrew Welch · Insights · #devops #craftcms #performance

Published , updated · 5 min read ·


Please consider 🎗 sponsoring me 🎗 to keep writing articles like this.

Installing mozjpeg on Ubuntu 16.04 & 18.04 (Forge)

If you want to go the extra mile opti­miz­ing your images, here’s how to install mozjpeg on Ubun­tu 16.04 or 18.04 (Forge)

Updat­ed for the new CMake-based build system.

For those of you who read the Cre­at­ing Opti­mized Images in Craft CMS arti­cle, and are inter­est­ing in going the extra mile… there is anoth­er loss­less JPEG image opti­miza­tion tool called mozjpeg that you might want to utilize.

The rea­son I did­n’t include it in the orig­i­nal arti­cle is that there’s no pack­age that you can just apt-get install. It requires a lit­tle more work, but it’s worth it. In my tests, I’m sav­ing between 3-5% on the images cre­at­ed with mozjpeg vs. jpegoptim, depend­ing on the image. Here’s a nice Com­par­i­son of JPEG Loss­less Com­pres­sion Tools if you like look­ing at stats.

For exam­ple, here’s an image I used in my blog in its unop­ti­mized (but prop­er­ly resized) glory:

unop­ti­mized image: 82,011 bytes

Next, the image opti­mized with jpegoptim:

jpe­gop­tim image: 81,950 bytes

And here is the same image opti­mized with mozjpeg:

mozjpeg image: 79,822 bytes

Can you tell the dif­fer­ence between these images? You should­n’t, because the opti­miza­tion is loss­less. The image itself is unchanged. The sav­ings are not a huge dif­fer­ence in terms of jpegoptim vs. mozjpeg (81,950 bytes vs 79,822 bytes), but 2k is 2k… and the dif­fer­ence can be more than this ~3% sav­ings depend­ing on the image.

jpegoptim went from 82,011 bytes in the orig­i­nal image to 81,950 bytes, a sav­ings of just 0.07%

mozjpeg went from 82,011 bytes in the orig­i­nal image to 79,822 bytes, a sav­ings of 2.66%

Obvi­ous­ly the huge gains in opti­miz­ing images are in ensur­ing that they are prop­er­ly sized & com­pressed to begin with, which these were, cour­tesy of Imager. But lop­ping off the unnec­es­sary cruft in a loss­less man­ner via mozjpeg is the cher­ry on top.

And it’s not that hard to install it. So if you’re on-board, and feel com­fort­able using a ter­mi­nal… away we go!

The instruc­tions here were all done on a VPS run­ning Ubun­tu 16.04 or 18.04 via Forge. They also work fine on my local dev Home­stead envi­ron­ment, which is also Ubun­tu 16.04.

First, make sure you have all of the pack­ages we need to build mozjpeg installed via:

sudo apt-get update
sudo apt-get install cmake autoconf automake libtool nasm make pkg-config git

Next cd to your build direc­to­ry (just cd ~ is prob­a­bly fine) and clone the git repo:

git clone https://github.com/mozilla/mozjpeg.git

Then do the fol­low­ing to con­fig­ure and com­pile mozjpeg 3.x:

cd mozjpeg
mkdir build && cd build
sudo cmake -G"Unix Makefiles" ../

Go grab a cup of cof­fee, the cmake com­mand will take a bit. Now we need to install it; by default it’ll be installed in /opt/mozjpeg directory:

sudo make install

Now we’ll cre­ate a sym­link to the spe­cial mozjpeg ver­sion of jpegtran into a path that’s in our $PATH (and where Imager expects it to be):

sudo ln -s /opt/mozjpeg/bin/jpegtran /usr/bin/mozjpeg

Then go into the imager plu­g­in fold­er, dupli­cate the config.php file, rename it imager.php, and copy that imager.php file into your craft/config direc­to­ry. This file lets us cus­tomize how Imager works. Open the imager.php file up in your text edi­tor, and enable mozjpeg like this:

'mozjpegEnabled' => true,
  'mozjpegPath' => '/usr/bin/mozjpeg',

Make sure you set 'jpegoptimEnabled' => false, if you were using jpegoptim already. I also do this:

'optimizeType' => 'runtime',

…so that Imager opti­mizes the images imme­di­ate­ly, rather than via a task, because I had a sit­u­a­tion where my CDN was grab­bing & caching the images before the Imager task opti­mized them.

That’s it! Enjoy your super-opti­mized images, and con­grats on going the extra mile!

I’d also high­ly sug­gest read­ing the arti­cle Using WebP images in Craft with Imager to add webp sup­port via Imager.