判斷瀏覽器是否支持 webp 的幾種解決方法

我們都知道,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];
}

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 注明:本人原創(chuàng)翻譯,原版為Essential Image Optimization電子書(shū),這里將其拆分為幾篇文章發(fā)...
    ProteanBear閱讀 5,461評(píng)論 0 5
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標(biāo)準(zhǔn)。 注意:講述HT...
    kismetajun閱讀 28,886評(píng)論 1 45
  • 本文原文來(lái)源于自家個(gè)人博客站 捷搜索 >> 判斷瀏覽器是否支持WebP圖片, 上篇文章“什么是WebP圖片?”...
    捷搜索閱讀 4,503評(píng)論 0 2
  • 最近,我們?cè)陧?xiàng)目中實(shí)踐了webp圖片,并且抽離出了工具模塊,整合到了項(xiàng)目的基礎(chǔ)模板中。傳聞IOS10也將要支持we...
    單純的土豆閱讀 2,388評(píng)論 1 15
  • 你以不變的模樣 熄滅我的過(guò)往 爬山虎的腳印 我的身影 都是太陽(yáng)的奴隸 為此我終止流浪 站在你綻放的地方 我虔誠(chéng)仰望...
    夏知寒閱讀 808評(píng)論 0 0

友情鏈接更多精彩內(nèi)容