jusewe 2019-11-17
我们都知道,WebP 是 Google 推出的 WebP 图片格式,它是一种支持有损压缩和无损压缩的图片文件格式,根据Google测试,相同的图片,WebP 格式的图片均能比 PNG,JPG 格式的图片节约不少体积,但是其兼容性不是很好,如下:
因此我们需要做一些兼容处理,那么如何判断浏览器支持 webp 呢?下面有几种方法可供参考。
使用 canvas 的 toDataURL 进行判断
toDataURL方法在MDN解释如下:
HTMLCanvasElement.toDataURL() 方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。
toDataURL方法将图片转化为包含dataURI的DOMString,通过 base64 编码前面的图片类型值是image/webp进行判断。
比如在谷歌浏览器使用toDataURL方法转成image/webp:
在 Safari 浏览器使用toDataURL方法转成image/webp:
可以发现在不支持 webp 的浏览器进行toDataURL,得到的图片类型并不是 webp,因此我们可以通过这个进行判断。
实现方法:
var isSupportWebp = function () { try { return document.createElement('canvas').toDataURL('image/webp', 0.5).indexOf('data:image/webp') === 0; } catch(err) { return false; } } isSupportWebp()
在服务端根据请求header信息判断浏览器是否支持webp
谷歌浏览器上请求图片 header是这样的:
IE 浏览器请求图片 header是这样的:
在图片请求发出的时候,Request Headers 里有 Accept,服务端可以根据Accept 里面是否有 image/webp 进行判断。
通过加载一张 webp 图片进行判断
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) })
此方法会加载一张 1x1 的白色的正方形背景图,用来测试浏览器是否支持 webp。
在 Google 测试代码:
在 Firefox 测试代码:
在 Safari 测试代码:
Google官方文档是这样处理的(先加载一个WebP图片,如果能获取到图片的宽度和高度,就说明是支持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]; }