Speed up your Ruby on Rails application using WebP images

Hello my dear friends.Today we will speed up our rails applications using webp images.

What is WebP?

WebP is an image format that employs both lossy and lossless compression. It’s been developed by Google and, as we can see on this page, so far only Google Chrome (+ Android) and Opera support this type of images. For our purposes though it doesn’t matter much, as we can show webp images in Chrome and Opera, and png, jpg or gif images in the other browsers.

WebP and Ruby on Rails

After the webp library has been released, I wrote a webp gem – webp-ffi. You can use it to work with webp images in Ruby. Also, two good Ruby gems were released a bit later – sprockets-webp and carrierwave-webp. Sprockets-webp provides a Rails Asset Pipeline hook for converting PNG and JPEG assets to the WebP format. To use it, just add this gem in the Gemfile:
gem 'sprockets-webp'
And run:
$ bundle
Put some PNGs and JPGs into “app/assets/images” and you can test converter locally with the Rake task:
$ bundle exec rake assets:precompile RAILS_ENV=production
Now for each image webp will be created:
$ ls public/assets | grep webp
app_view-c1c11c4587eb1e6583df7825b76354eb.png.webp
bg-51830e3641c265cb246d752c57df3c20.jpg.webp
favicon-c594206ef399e642bd7024986158976c.png.webp
feature01-62e93a154b58089fe25e63a4e5087cf2.png.webp
feature02-24ee54e80423624080977fc17828bf23.png.webp
feature03-67de13538e75226fcdb1e4dd15d258bb.png.webp
feature04-28c1d1d55b982341f371ef519df06d36.png.webp
feature05-54a3ca87cd4ea2b4d8c6476181940b95.png.webp
feature06-7a7881a2640f8b879ec4defeb07e7d9b.png.webp
feature07-4b206a44dbf7181a1f653b157b8183de.png.webp
feature08-800ee165d1e6e854f55d92282a2df09d.png.webp
icon01-93581fe0eeaab8d135282a15f5ef8e3f.png.webp
icon02-e8efdd17d3f1f5d13f1d878240d55970.png.webp
icon03-1f3e94e02160b9fbeb2036490973150d.png.webp
logo-e424b8ca2552edb04331faf0da7f213c.png.webp
signin_block-3af7fa120ca9a6ea11d7bf63c1ec062b.png.webp
toggle-ae225a8eda983bb3344c2f496749cb3e.png.webp
If you want to convert images uploaded by users to your application, you can use carrierwave-webp (of course, if you use for this purpose carrierwave gem).

Nginx with WebP

We have to show webp images only in browsers supporting this format and we’ll use Ngnix web server for this. Chrome and Opera advertise image/webp on its Accept header for all image requests. Now, we have to configure our Nginx server to choose the right file automatically.
location ~ ^/(assets)/  {
   # check Accept header for webp, check if .webp is on disk
   if ($http_accept ~* "webp") { set $webp "true"; }
   if (-f $request_filename.webp) { set $webp "${webp}-local"; }
   if ($webp = "true-local") {
    add_header Vary Accept;
    access_log   off;
    expires      30d;
    rewrite (.*) $1.webp break;
   }

   root /some/folder/current/public;
   expires max;
   add_header  Cache-Control public;
   access_log  off;
   gzip_static  on;
   gzip_proxied any;
   break;
}
Then, we check if the Accept header is an advertising WebP and if there’s a corresponding file with a .webp extension on disk. If both conditions match, we serve the WebP asset and add “Vary: Accept” header.

Results

We can now view the results. First, we check the speed of loading of our assets in Firefox (full image):Firefox WebpAs we can see, a lot of big images have a size of 145.07 Kb. Now let’s check the result in Chrome (full image):Chrome WebpImage with a size of 145.07 Kb was converted into webp image with a size of 17.2 Kb. Other images now also have smaller sizes than png or jpeg images. By the way, the visual quality of images has not become worse.WebpAs the result, we reduced load time of rails application almost twice: from an average time of 800ms to an average page response time of 500ms.

Summary

Using webp images allowed us to accelerate load speed of our application in Chrome and Opera browsers. Hopefully, Firefox (and may be even IE) will also support this image format one day.This is a re-post from my blog.