Cloudinary Blog

Quick Guide: Using WebP on Your Website or Native Apps

Using WebP on Your Website or Native Apps

JPEG and PNG are the predominant formats used for image delivery on the web. According to a W3Techs survey, 74 percent of the websites worldwide use these formats, and for good reason: They are supported across all browsers. Still, there are newer image formats with better performance and a leading example is the WebP format. Here we'll show how to easily implement WebP in order to reduce your images weight by approx. 30 percent and improve your website and native apps image load time.

What is WebP?

WebP is a modern image format developed by Google that is specifically designed for web delivery. It aims at creating smaller, better looking images that can help make the web faster. WebP typically achieves an average of 30% more compression than JPEG, without loss of image quality. Interestingly enough WebP is only supported by Chrome, Android and Opera browsers, which would be a compelling reason not to use it. However, Chrome usage has risen year-over-year, reaching 75 percent according to W3Schools survey. Opera adds another 1 percent, which means that optimization for Chrome (and Opera) is worth pursuing.

What about my native mobile apps?

Looking into support for native apps, WebP is supported by Android (since it’s made by Google). Lossy WebP images are supported in Android 4.0 (API level 14) and higher, and lossless and transparent WebP images are supported in Android 4.3 (API level 18) and higher. WebP can also be implemented on iOS by using a dedicated library to encode and decode images. The library, is called libwebp, is available as precompiled binaries for iOS or as source code.

WebP supports:

  • Lossy and lossless compression options
  • Transparency
  • XMP (Extensible Metadata Platform) metadata
  • ICC (International Color Consortium) profiles
  • Animation
  • Color Space:
    • Lossy WebP works exclusively with 8-bit YUV420 format.
    • Lossless WebP works exclusively with RGBA format.

Side by Side Comparison

JPEG -> WebP (Resolution: 300x190, Quality: 80)

JPEG JPEG(15KB) WebP WebP(10KB)

PNG -> WebP (Resolution: 300 x 192. Image with transparency)

PNG PNG(55KB) WebP WebP(39KB)

A GIF -> A WebP (Resolution: 300x168, Quality: 80. Animation)

GIF GIF(2.23MB) Animated WebP Animated WebP(887KB)

Implementing WebP Using <picture>

One way to implement WebP is using <picture>, which enables you to define different image sources. The browser will download the first option, according to the supported type. However this will require using a polyfill, such as picturefill, for browsers that don’t support HTML5 picture tag.

<picture>
  <source type="image/webp" srcset="images/cat.webp">
  <img src="images/cat.jpg" alt="a cat">
</picture>

Easy Implementation for Web delivery

Instead of creating a WebP variant for each image, let's explore an easier alternative. Once an image is uploaded to Cloudinary, you can request it to be sent in the optimal image format according to the user browser. In case the image is requested from Chrome (or Opera), it will be automatically converted to WebP on the first request and then cached on the CDN for any subsequent request. By using the same URL for all image formats, effortlessly saving 30 percent image bandwidth on average. Using this method with Cloudinary also will deliver the image as JPEG to Firefox users and convert the image the same way to JPEG-XR for IE users (see more on automatic format).

Ruby:
cl_image_tag("dog2.jpg", :width=>500, :height=>333, :crop=>"fill", :fetch_format=>:auto)
PHP:
cl_image_tag("dog2.jpg", array("width"=>500, "height"=>333, "crop"=>"fill", "fetch_format"=>"auto"))
Python:
CloudinaryImage("dog2.jpg").image(width=500, height=333, crop="fill", fetch_format="auto")
Node.js:
cloudinary.image("dog2.jpg", {width: 500, height: 333, crop: "fill", fetch_format: "auto"})
Java:
cloudinary.url().transformation(new Transformation().width(500).height(333).crop("fill").fetchFormat("auto")).imageTag("dog2.jpg");
JS:
cloudinary.imageTag('dog2.jpg', {width: 500, height: 333, crop: "fill", fetchFormat: "auto"}).toHtml();
jQuery:
$.cloudinary.image("dog2.jpg", {width: 500, height: 333, crop: "fill", fetch_format: "auto"})
React:
<Image publicId="dog2.jpg" >
  <Transformation width="500" height="333" crop="fill" fetchFormat="auto" />
</Image>
Angular:
<cl-image public-id="dog2.jpg" >
  <cl-transformation width="500" height="333" crop="fill" fetch-format="auto">
  </cl-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(500).Height(333).Crop("fill").FetchFormat("auto")).BuildImageTag("dog2.jpg")
Android:
MediaManager.get().url().transformation(new Transformation().width(500).height(333).crop("fill").fetchFormat("auto")).generate("dog2.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setWidth(500).setHeight(333).setCrop("fill").setFetchFormat("auto")).generate("dog2.jpg")!, cloudinary: cloudinary)
Dog

Native Mobile Apps Support

In the case of a native mobile app, the WebP format can be fixed for the Android app using the same image already uploaded to Cloudinary and used for the web. For the native app, we can use the Android SDK or simply construct the URL.

On your Android App:

cloudinary.url().transformation(new Transformation().width(500).height(333).crop("fill")).fetchFormat("webp")).generate("dog.jpg")

The equivalent URL is: https://res.cloudinary.com/cld-name/image/upload/c_fill,f_webp,h_333,w_500/dog.jpg

Adding Quality to the Game

The image quality setting, which is used to define the depth of the lossy compression, has an effect on the results as well. Finding the sweetspot for your images require analyzing which quality setting fits them. For example, you may test quality 80 and quality 90 to verify the image weight reduction and whether it meets the required visual quality.

However, since each image eventually has it own optimal quality setting, using Cloudinary’s automatic quality option (q_auto) will automatically find the quality level for each image according to the required visual level (more on automatic quality). Using both automatic format and quality achieves full automation and lets Cloudinary decide on-the-fly the best quality setting and format to deliver. The visual quality level itself can be set according to the delivery method. For example, you can use the default “good” visual quality level on the web and an “eco” level on your native mobile app in order to save more bandwidth.

Using Automatic Quality for Full Automation

On your website:

Ruby:
cl_image_tag("dog2.jpg", :width=>500, :height=>333, :quality=>"auto", :crop=>"fill", :fetch_format=>:auto)
PHP:
cl_image_tag("dog2.jpg", array("width"=>500, "height"=>333, "quality"=>"auto", "crop"=>"fill", "fetch_format"=>"auto"))
Python:
CloudinaryImage("dog2.jpg").image(width=500, height=333, quality="auto", crop="fill", fetch_format="auto")
Node.js:
cloudinary.image("dog2.jpg", {width: 500, height: 333, quality: "auto", crop: "fill", fetch_format: "auto"})
Java:
cloudinary.url().transformation(new Transformation().width(500).height(333).quality("auto").crop("fill").fetchFormat("auto")).imageTag("dog2.jpg");
JS:
cloudinary.imageTag('dog2.jpg', {width: 500, height: 333, quality: "auto", crop: "fill", fetchFormat: "auto"}).toHtml();
jQuery:
$.cloudinary.image("dog2.jpg", {width: 500, height: 333, quality: "auto", crop: "fill", fetch_format: "auto"})
React:
<Image publicId="dog2.jpg" >
  <Transformation width="500" height="333" quality="auto" crop="fill" fetchFormat="auto" />
</Image>
Angular:
<cl-image public-id="dog2.jpg" >
  <cl-transformation width="500" height="333" quality="auto" crop="fill" fetch-format="auto">
  </cl-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(500).Height(333).Quality("auto").Crop("fill").FetchFormat("auto")).BuildImageTag("dog2.jpg")
Android:
MediaManager.get().url().transformation(new Transformation().width(500).height(333).quality("auto").crop("fill").fetchFormat("auto")).generate("dog2.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setWidth(500).setHeight(333).setQuality("auto").setCrop("fill").setFetchFormat("auto")).generate("dog2.jpg")!, cloudinary: cloudinary)
Dog

On your Android App:

cloudinary.url().transformation(new Transformation().width(500).height(333).crop("fill")).fetchFormat("webp").quality("auto:eco")).generate("dog.jpg")

The equivalent URL is: https://res.cloudinary.com/cld-name/image/upload/c_fill,f_webp,h_333,q_auto:eco,w_500/dog.jpg

Summary

Managing images can be challenging because supporting the same image with different sizes and crops for responsive design requires significant development effort. Still, since images are 60 percent to 65 percent of the average website, the savings are significant and therefore automating the process makes a lot of sense. Luckily all of this can be done on-the-fly using Cloudinary, so you can benefit from the advantages WebP provides without requiring additional development effort to support it.

Recent Blog Posts

Integrating Cloudinary with Forestry’s Media Library

At Forestry, we believe that there is a bright future for static HTML sites built with tools like Jekyll and Hugo. These tools can create sites that run well, and are easy to host and maintain, because they don’t require any server-side code.

Read more
Video Optimization With the HTML5 <video> Player

Lack of experience and compression knowhow can cause significant user-experience problems. For instance, on a major retail site, I recently ran into a 48 MB video-hero banner. Pulling out the video and encoding it as an H.264 MP4 reduces the size to 1.9 MB. So, despite the desire for more video content, developers have not yet caught up to best practices. How do we get the best of both worlds without creating a disaster like the one above?

Read more
Build a Facial Emotion Recognition Based Video Suggestion App

Developers are always looking for new and creative ways to deliver content that resonates with the way users feel. Often using the latest technical innovations the market has to offer such as Artificial Intelligence (AI) and Machine Learning (ML). What better way to demonstrate innovative uses of these technology in a consumer market than capturing expressions from your users and then serving content based on that expression!

Read more
Improve Customer Data Protection with GDPR Implementation

TL;DR

Yay! We've done it! Gold-Star for us! We've talked with all the people, made all the changes, paid all the lawyers and checked all the boxes. GDPR? ✅Done!

Not so fast. Of course, conforming to the GDPR regulations introduced in Europe is just the beginning. This is a process and a state of mind that must become part of our long-term cultural ethos.

Read more
Magento Image and Video Optimization

As the number of channels and devices continues to grow, it is becoming much more challenging to deliver an optimal visual experience. On an eCommerce site, engagement and conversions are critical. Factors such as page load time strongly influence search engine rankings, shopping experiences, conversion rates and, ultimately, your revenue. An optimized visual experience positively affects conversion rates. But it also can introduce resource bottlenecks, as every image and video needs to be delivered in the most efficient format, quality and resolution, based on the viewing device.

Read more