I've been working on improving my website speed performance, I normally use google Page Speed Insights to check my score and previously I had pretty much got the best score possible but since January 2018 google updated the tool to use Lighthouse I didn't pay much attention to it until recently and I discovered that my score was lower and the tool had new suggestions for me that didn't have before. This was good since after implementing those recommendations I learned a few new tricks and my website got a lot faster.

You have a few ways to use this tool one is integrated into your google chrome developers tools and another one is going into the link I shared before and simply enter the URL to the page you would like to measure. I'm going to proceed using the page and see how is my website currently doing.

google-page-speed-insights

Page speed insights split your results into two different tabs one for desktop and another one for mobile. The following is my desktop result which is pretty good.

google-page-speed-insights-results

For mobile, it's more strict and my result is not that great.

google-page-speed-insights-mobile-results

The good think about the tool is that not only it gives you a Score but it also give you recommendations and an estimated of how much load time you could save implementing those. On my case, it suggested three and the first one that got my attention was "Serve images in next-gen formats"

google-page-speed-insights-recommendationst

You can see it's telling me I could gain up to half a second load time and it's listing a lot of my images, this caught my attention because to my knowledge I was already using the best possible compression and achieving the best image size I could get without losing quality, but of course, this is the web and things move fast. The promise of these next-gen formats is:

Provide better compression than PNG or JPEG, which means faster download times and less data consumption.
You can find more info about the recommendation on the learn more link that they put there, that one should take you here: Serve Images in Next-Gen Formats

Browser Support

You can see that these new formats are JPEG 2000, JPEG XR, and WebP, everything was going well until I got to the browser support part, which at the time that I'm writing this post is that none of these of them is soported in all major browsers (Chrome, Firefox, Edge, Safari, and Opera). You can check the support for each individual format here:

  • WebP (Supported in all major browser except Safari)
  • JPEG 2000 (Supported only in Safari)
  • JPEG XR (Supported only in Edge and IE)

The one that currently has broader support is WebP however leaving Safari out is not good so this almost became a show stopper for me, fortunately, I continued reading about ways to implement fallback techniques so that if the user is using Safari I could load the image in a different format that is supported.

Picture tag

Picture tag is very helpful it give us developers more flexibility in specifying image resources and while the most common use is for conditionally load images for responsive designs it can also help us implementing a fallback technique for supported image formats. This is how I had to transform my <img /> tags in order to use Webp but also being able to fall back to png in case Webp is not supported

This is how my normal <img /> tags looks like: Nothing special about it, now in order to transform it into a picture that would load a Webp format if supported and if not it would load the corresponding png image I must transform my HTML to:

That's it nothing more to do regarding code, with just HTML I can use webp with fallback to jpg in case is not supported

Transforming to WebP format

Now that I know how to handle WebP formats with a fallback when is not supported the next step is actually transforming my png image to webp, there are several free online image editors that could do this for you but if you need to transform lots of images there are also great CLI tools on Nodejs that you could use and even hook up to your current build pipeline. In order to keep this simple, I'm going to use an online editor called squoosh by Google Chrome Labs, this is an amazing and easy to use tool just go to the link and Drag and Drop an image or click Select an image

squoosh-homepage
squoosh-editor

You can see that formatting my already optimized png is making the image size go from 67.4kB to 7.12kB which is 86% smaller and without losing quality. This is impressive if you ask me. You might play around with the options I noticed sometimes checking Lossless give me a greater reduction in size.

Results

On my case I'm going to begin with the main image I load at my home page and after converting to webp and using picture you can see on my browser that is correctly loading the webp image

main-page

You can tell that the quality is not compromised and comparing the webp image to the png you can see there is a big difference in size.

cmder-results

One drawback of this approach is that I have to keep "Duplicated" of each image but for me, it's worth it and once it's correctly setup with a CLI tool you don't need to manually create the images for each format

Background images

There is another way for you to load images which is trough the css background-image and I'm actually using it so my code looks like this:

background: url('../images/home-bg.jpg') no-repeat scroll center center;

If I want to use webp images there I would also run into the support for Safari problem so I have to implement a fallback for this too, I need to detect browser support for webp and a very popular library to do that is modernizr, in fact, you can create your custom build of the library with just the features you want to detect and since I'm in the business of optimizing for speed I'll do that.

modernizr-custom-buildt

After selection the features you want to detect click on build and select the way you would like to get your custom build.

modernizr-custom-build-get

On my case I went for open build in codepen.io so that I can copy and paste from there and I even get a usage example/demo right there on codepen.

modernizr-codepen-build

What modernizr will do for me is add the class .no-webp to the html tag that way I can create css rule specific for when there is no webp support on the browser the code ends up like this


    my-selector {
        background: url('../images/home-bg.webp') no-repeat scroll center center
    }

    .no-webp my-selector {
        background: url('../images/home-bg.jpg') no-repeat scroll center center
    }

With this, I can now safely use webp images as background too

background-url-loads

Test Safari Support

Now I also need to test my site on Safari to make sure it's working properly.

safari-test-1

You can see that the picture tag is working correctly and loading the jpg image since it doesn't support webp, and in order to load my background images from css modernizr it's doing its job and adding the no-webp class.

safari-test-2

So the proper image is being loaded.

safari-test-3

Final Score

So after running page speed insights again I get a new score.

final-mobile-score

Going from 69 to 78 is a good increase not to mention the main page nows load half a second faster, I still have other recommendations to implement and I'll be blogging my findings. Here you can see how I implemented Defer OffScreen Images

Do you think webp is worth the trouble? Is there any CLI tool that you have successfully implemented on your build to support webp formats?