Content posted here with the permission of the author Shivam Kumar Singh, who is currently employed at Josh Software. Original post available here
Since internet is born, we have come a long way in improving web page loading time. Faster it gets, better it is. Most time consuming part of loading web & mobile app is loading images. Therefore faster image load is major challenge today.
One of application we worked recently has lots of images to render. As number of images increased, loading time of application increased as well.
So to tackle this problem we decided to compress images. We were using ImageMagick with carrierwave for all the image processing and remote file upload. So we decided to compress the image using ImageMagick libraries to reduce the file size but it compresses the image at the cost of image quality. We can not compromise on image quality therefore we were looking for alternatives.
We came across webp format developed by Google — which uses both lossy and lossless compression. WebP lossless images are 26% smaller in size compared to PNGs.
Can you figure out size of below images by looking at them ?
Image 1 is of type jpg and Image 2 is of type webp.
Quality wise they look very similar, right ? But size wise Image 1 is 4 times larger than Image 2
Image 1 size is 2.8 MB while Image 2 size is 551 KB.
How to configure it for Rails Application
Considering we already have ImageMagick installed on our system.
We have to install libwebp, a library used to add WebP encoding and decoding to your programs. Before that
Download dependency for libwebp.
sudo apt-get install libjpeg-dev libpng-dev libtiff-dev libgif-dev
Download latest libwebp and extract it.
wget http://downloads.webmproject.org/releases/webp/libwebp-0.4.3.tar.gz tar xf libwebp-0.4.3.tar.gz
Run the following commands to install libwebp.
cd libwebp-0.4.3/ ./configure make sudo make install
Run following command on the console to confirm successful installation.
2.0.0p0 :002 > WebP.decoder_version => "0.4.3"
2.0.0p0 :003 > WebP.encoder_version => "0.4.3"
Now we need to add carrierwave-webpgem which is Ruby wrapper for libwebp.
Now that we have all of our prerequisites out of the way, we are now ready to convert our image to WebP.
Customize Carrierwave uploader to generate images in webp format.
class MediaUploader < CarrierWave::Uploader::Base include CarrierWave::MiniMagick include CarrierWave::WebP::Converter version :jpeg do process resize_to_fit: [720, 450] process convert: :jpeg end version :webp do process :convert_to_webp end end
So this way we have generated two different versions of images, one in jpg with given resolution (for fallback) and other in webp format.
Format Specific remote image URL
def return_url(poster, format) if poster.image.send(format).exists? url = poster.image.send(format).url else poster.image.jpeg.url //JPEG as fallback option. end end
There are few limitations as well for webp
- Not supported in iOS and Safari client.
- More effective for substantially large files
With Webp format, we decreased our images size by 4 times thereby increased page load speed. If you have any questions let us know in comments.