Skip to main content

How to detect if the Webp image format is supported in the browser with JavaScript


The WebP image format, is known for providing a superior lossless and lossy compression for images around the web. Using WebP, webmasters and web developers can create smaller, richer images that make the web incredibly faster. WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index. For more information about this format, please be sure to read its introduction by the Google Developers here. Till the date, you can't verify wheter this format is supported in the browser in JavaScript using a predefined method, however you can create your own method to do it using a little trick.

The logic to verify if the webp format is supported with Plain JavaScript is the following: the first you need is a base64 string with some image in webp format, in this case we'll use a white image of 1px that is already in this format, then this string needs to be converted into a Blob. There are many ways to convert a base64 string to a blob, however one of the most easiest is using the fetch API that is available in the browser and then calling the blob method from it. This will be already a blob that can be interpreted by the createImageBitmap function of the browser. The createImageBitmap method exists on the global in both windows and workers. It accepts a variety of different image sources, and returns a Promise which resolves to an ImageBitmap.

In this article, we'll share with you 2 methods that will help you to verify if this format is supported on your browser with different JavaScript versions.

Standard JavaScript

Using the tipical approach with callbacks that is supported everywhere (as long as the fetch API is supported)

function WebpIsSupported(callback){
    // If the browser doesn't has the method createImageBitmap, you can't display webp format
    if(!window.createImageBitmap){
        callback(false);
        return;
    }

    // Base64 representation of a white point image
    var webpdata = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoCAAEAAQAcJaQAA3AA/v3AgAA=';

    // Retrieve the Image in Blob Format
    fetch(webpdata).then(function(response){
        return response.blob();
    }).then(function(blob){
        // If the createImageBitmap method succeeds, return true, otherwise false
        createImageBitmap(blob).then(function(){
            callback(true);
        }, function(){
            callback(false);
        });
    });
}

Then you can use the method like:

// You can run the code like !
WebpIsSupported(function(isSupported){
    if(isSupported){
        console.log("Supported");
    }else{
        console.log("Not supported");
    }
});

ES2017

With ECMAScript 2017 you can simplify all the previous code using asynchronous functions instead of callbacks:

async function WebpIsSupported() {
    // If the browser doesn't has the method createImageBitmap, you can't display webp format
    if (!self.createImageBitmap) return false;
  
    // Base64 representation of a white point image
    const webpData = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoCAAEAAQAcJaQAA3AA/v3AgAA=';
    
    // Retrieve the Image in Blob Format
    const blob = await fetch(webpData).then(r => r.blob());

    // If the createImageBitmap method succeeds, return true, otherwise false
    return createImageBitmap(blob).then(() => true, () => false);
}

And you can test if the format is supported like:

// You can run your code like
(async () => {
    if(await WebpIsSupported()) {
        console.log('Is Supported');
    } else {
        console.log("Isn't supported");
    }
})();

Redundancy? I think yes.

Although till this point we don't have a real use-case more than to optimize image loading on application, this implementation is more informative as it can provide an idea of how to check easily if the format is supported in the browser or not. The funniest thing on the initial snippet (standard JavaScript), is that if you will include the snippet on your application and this will run on older browsers, you will need as well check for support of the fetch API and an extra way to convert the base 64 string to a blob and then use that blob with the createImageBitmap method. Checking if the fetch API is supported or using a polyfill for it, will lead to another dependency, namely the support for Promises.

Comments

Popular posts from this blog

4 Ways to Communicate Across Browser Tabs in Realtime

1. Local Storage Events You might have already used LocalStorage, which is accessible across Tabs within the same application origin. But do you know that it also supports events? You can use this feature to communicate across Browser Tabs, where other Tabs will receive the event once the storage is updated. For example, let’s say in one Tab, we execute the following JavaScript code. window.localStorage.setItem("loggedIn", "true"); The other Tabs which listen to the event will receive it, as shown below. window.addEventListener('storage', (event) => { if (event.storageArea != localStorage) return; if (event.key === 'loggedIn') { // Do something with event.newValue } }); 2. Broadcast Channel API The Broadcast Channel API allows communication between Tabs, Windows, Frames, Iframes, and  Web Workers . One Tab can create and post to a channel as follows. const channel = new BroadcastChannel('app-data'); channel.postMessage(data); And oth...

Certbot SSL configuration in ubuntu

  Introduction Let’s Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free  TLS/SSL certificates , thereby enabling encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps. Currently, the entire process of obtaining and installing a certificate is fully automated on both Apache and Nginx. In this tutorial, you will use Certbot to obtain a free SSL certificate for Apache on Ubuntu 18.04 and set up your certificate to renew automatically. This tutorial will use a separate Apache virtual host file instead of the default configuration file.  We recommend  creating new Apache virtual host files for each domain because it helps to avoid common mistakes and maintains the default files as a fallback configuration. Prerequisites To follow this tutorial, you will need: One Ubuntu 18.04 server set up by following this  initial ...

Working with Node.js streams

  Introduction Streams are one of the major features that most Node.js applications rely on, especially when handling HTTP requests, reading/writing files, and making socket communications. Streams are very predictable since we can always expect data, error, and end events when using streams. This article will teach Node developers how to use streams to efficiently handle large amounts of data. This is a typical real-world challenge faced by Node developers when they have to deal with a large data source, and it may not be feasible to process this data all at once. This article will cover the following topics: Types of streams When to adopt Node.js streams Batching Composing streams in Node.js Transforming data with transform streams Piping streams Error handling Node.js streams Types of streams The following are four main types of streams in Node.js: Readable streams: The readable stream is responsible for reading data from a source file Writable streams: The writable stream is re...