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

How to use Ngx-Charts in Angular ?

Charts helps us to visualize large amount of data in an easy to understand and interactive way. This helps businesses to grow more by taking important decisions from the data. For example, e-commerce can have charts or reports for product sales, with various categories like product type, year, etc. In angular, we have various charting libraries to create charts.  Ngx-charts  is one of them. Check out the list of  best angular chart libraries .  In this article, we will see data visualization with ngx-charts and how to use ngx-charts in angular application ? We will see, How to install ngx-charts in angular ? Create a vertical bar chart Create a pie chart, advanced pie chart and pie chart grid Introduction ngx-charts  is an open-source and declarative charting framework for angular2+. It is maintained by  Swimlane . It is using Angular to render and animate the SVG elements with all of its binding and speed goodness and uses d3 for the excellent math functio...

JavaScript new features in ES2019(ES10)

The 2019 edition of the ECMAScript specification has many new features. Among them, I will summarize the ones that seem most useful to me. First, you can run these examples in  node.js ≥12 . To Install Node.js 12 on Ubuntu-Debian-Mint you can do the following: $sudo apt update $sudo apt -y upgrade $sudo apt update $sudo apt -y install curl dirmngr apt-transport-https lsb-release ca-certificates $curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - $sudo apt -y install nodejs Or, in  Chrome Version ≥72,  you can try those features in the developer console(Alt +j). Array.prototype.flat && Array.prototype. flatMap The  flat()  method creates a new array with all sub-array elements concatenated into it recursively up to the specified depth. let array1 = ['a','b', [1, 2, 3]]; let array2 = array1.flat(); //['a', 'b', 1, 2, 3] We should also note that the method excludes gaps or empty elements in the array: let array1 ...

Understand Angular’s forRoot and forChild

  forRoot   /   forChild   is a pattern for singleton services that most of us know from routing. Routing is actually the main use case for it and as it is not commonly used outside of it, I wouldn’t be surprised if most Angular developers haven’t given it a second thought. However, as the official Angular documentation puts it: “Understanding how  forRoot()  works to make sure a service is a singleton will inform your development at a deeper level.” So let’s go. Providers & Injectors Angular comes with a dependency injection (DI) mechanism. When a component depends on a service, you don’t manually create an instance of the service. You  inject  the service and the dependency injection system takes care of providing an instance. import { Component, OnInit } from '@angular/core'; import { TestService } from 'src/app/services/test.service'; @Component({ selector: 'app-test', templateUrl: './test.component.html', styleUrls: ['./test.compon...