我們都知道,WebP 是 Google 推出的 WebP 圖片格式,它是一種支持有損壓縮和無(wú)損壓縮的圖片文件格式,根據(jù)Google測(cè)試,相同的圖片,WebP 格式的圖片均能比 PNG,JPG 格式的圖片節(jié)約不少體積,但是其兼容性不是很好,如下:
因此我們需要做一些兼容處理,那么如何判斷瀏覽器支持 webp 呢?下面有幾種方法可供參考。
方法一
使用 canvas 的 toDataURL 進(jìn)行判斷
toDataURL方法在MDN解釋如下:
HTMLCanvasElement.toDataURL() 方法返回一個(gè)包含圖片展示的 data URI ??梢允褂?type 參數(shù)其類(lèi)型,默認(rèn)為 PNG 格式。圖片的分辨率為96dpi。
- 如果畫(huà)布的高度或?qū)挾仁?,那么會(huì)返回字符串“data:,”。
- 如果傳入的類(lèi)型非“image/png”,但是返回的值以“data:image/png”開(kāi)頭,那么該傳入的類(lèi)型是不支持的。
- Chrome支持“image/webp”類(lèi)型。
toDataURL方法將圖片轉(zhuǎn)化為包含dataURI的DOMString,通過(guò) base64 編碼前面的圖片類(lèi)型值是image/webp進(jìn)行判斷。
比如在谷歌瀏覽器使用toDataURL方法轉(zhuǎn)成image/webp:
在 Safari 瀏覽器使用toDataURL方法轉(zhuǎn)成image/webp:
可以發(fā)現(xiàn)在不支持 webp 的瀏覽器進(jìn)行toDataURL,得到的圖片類(lèi)型并不是 webp,因此我們可以通過(guò)這個(gè)進(jìn)行判斷。
實(shí)現(xiàn)方法:
var isSupportWebp = function () {
try {
return document.createElement('canvas').toDataURL('image/webp', 0.5).indexOf('data:image/webp') === 0;
} catch(err) {
return false;
}
}
isSupportWebp()
方法二
在服務(wù)端根據(jù)請(qǐng)求header信息判斷瀏覽器是否支持webp
谷歌瀏覽器上請(qǐng)求圖片 header是這樣的:

IE 瀏覽器請(qǐng)求圖片 header是這樣的:

在圖片請(qǐng)求發(fā)出的時(shí)候,Request Headers 里有 Accept,服務(wù)端可以根據(jù)Accept 里面是否有 image/webp 進(jìn)行判斷。
方法三
通過(guò)加載一張 webp 圖片進(jìn)行判斷
const supportsWebp = ({ createImageBitmap, Image }) => {
if (!createImageBitmap || !Image) return Promise.resolve(false);
return new Promise(resolve => {
const image = new Image();
image.onload = () => {
createImageBitmap(image)
.then(() => {
resolve(true);
})
.catch(() => {
resolve(false);
});
};
image.onerror = () => {
resolve(false);
};
image.src = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=';
});
};
const webpIsSupported = () => {
let memo = null;
return () => {
if (!memo) {
memo = supportsWebp(window);
}
return memo;
};
};
webpIsSupported()().then(res => {
console.log("是否支持 webp", res)
}).catch(err => {
console.log(err)
})
此方法會(huì)加載一張 1x1 的白色的正方形背景圖,用來(lái)測(cè)試瀏覽器是否支持 webp。
在 Google 測(cè)試代碼:

在 Firefox 測(cè)試代碼:

在 Safari 測(cè)試代碼:

Google官方文檔是這樣處理的(先加載一個(gè)WebP圖片,如果能獲取到圖片的寬度和高度,就說(shuō)明是支持WebP的,反之則不支持):
function check_webp_feature(feature, callback) {
var kTestImages = {
lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
};
var img = new Image();
img.onload = function () {
var result = (img.width > 0) && (img.height > 0);
callback(feature, result);
};
img.onerror = function () {
callback(feature, false);
};
img.src = "data:image/webp;base64," + kTestImages[feature];
}
