Explain Codes LogoExplain Codes Logo

Detecting WebP support

javascript
webp-support
image-loading
async-programming
Nikita BarsukovbyNikita Barsukov·Dec 25, 2024
TLDR

Easily check for WebP image format support in your browser with this neat JavaScript snippet:

const testWebP = new Image(); testWebP.onload = testWebP.onerror = function() { // Logs 'WebP support: true' or 'WebP support: false' console.log('WebP support:', testWebP.width === 1); }; testWebP.src = 'data:image/webp;base64,UklGRi4AAABXRUJQVlA4TCEAAAAvAUAAEB8wAiMw' + 'AgSSNtse/cXjxyCCmrYNWPwmHRH9jwMA';

Running this code will quickly test WebP support in the current browser.

In-depth explanation

Understanding the quick test

Let's decode our quick test:

  1. An Image object is created
  2. The onload and onerror event handlers are defined — one of them will fire (depending on support)
  3. The src attribute is set to a base64-encoded WebP image
  4. When the image loads, WebP support is confirmed (or denied), and it logs the support status

The canvas technique: supporting older browsers

Canvas gives us an alternative to WebP testing. Use elem.getContext(), to test browser canvas support:

const canvas = document.createElement('canvas'); if (canvas.getContext && canvas.getContext('2d')) { // This browser can handle a bit of doodling 🎨 // Paint away! }

If there's no canvas support, alternative methods like Modernizr or more traditionally, <picture> elements, may come handy.

Leverage HTML5 picture element

Utilize HTML5's <picture> element to provide alternative formats in case of no WebP support:

<picture> <source srcset="image.webp" type="image/webp"> <img src="image.jpg" alt="Non-WebP browsers get cake 🍰"> </picture>

It's like giving a straight-A student their golden star and a sweet kid their candy.

Optimizing with caching

Remember the old adage "Don't repeat yourself (DRY)"? We cache the WebP support detection result to save computational resources. Once you've checked, don't keep checking – just remember it:

let webpSupport; function checkWebP(callback) { if(webpSupport !== undefined) { // I remember this! 🧠 return callback(webpSupport); } // run detection as usual… }

Your CPU will thank you!

Deep dive into WebP features

WebP has several different features (like 'lossy', 'lossless', 'alpha', and 'animation'). You can check for each using specific test images. Get as specific as you wish.

Managing callbacks and async behaviour

As with all things JavaScript, we're living in asynchrony. You can either use callbacks or the more modern Promise to manage it when detecting WebP support:

function checkWebPSupport() { return new Promise((resolve) => { if(webpSupport !== undefined) // If I had a promise for every forgotten semicolon... 😉 resolve(webpSupport); // run detection as usual... }); }

Advanced techniques

Handling async image loading

For more advanced applications, apply asynchronous image loading to prevent blocking:

function detectWebPSupportAsync() { return new Promise((resolve) => { const testImage = new Image(); testImage.onload = () => resolve(testImage.width === 1); testImage.onerror = () => resolve(false); testImage.src = // base64 encoded WebP image string... }); }

Browser quirks

Remember, not all browsers are created equal! 🦓 Firefox 65, for example, has issues with synchronous WebP detection. Be mindful of these small gotchas when writing your detection code.

Accessibility is key

WebP support does not replace good habits. Always include an alt attribute for your images to ensure users with screen-readers can have a delicious web experience:

<img src="image.webp" alt="A description as sweet as sugar">