網頁性能提升之WebP

鑑於之前做的大屏的項目,全屏背景圖過大,傳統的寫法導致頁面渲染過慢,因而非常影響用戶體驗。

除此以外,很多時候在開發過程中會出現很多圖片的情況,圖片過多或大,會直接影響頁面的響應時間,從而導致頁面性能變差。

針對以上,我們可以使用WebP來有效的改善。

關於WebP

WebP格式,谷歌(google)開發的一種旨在加快圖片加載速度的圖片格式。圖片壓縮體積大約只有JPEG的2/3,並能節省大量的服務器寬帶資源和數據空間。
WebP既支持有損壓縮也支持無損壓縮。相較編碼JPEG文件,編碼同樣質量的WebP文件需要佔用更少的計算資源。

優勢

  • 圖片體積更小的情況下,圖像質量不變
  • 具有alpha透明和動畫特性
  • 更優的圖像數據壓縮算法

兼容性

webp兼容性
目前Chrome、Oprea以及較高版本的火狐等是支持WebP的,其實這個數量也一直在增加,未來可能會有更好的兼容性。

不過就目前來看,在使用webp的同時,還是需要對其不兼容的情況進行處理的

WebP在項目中的使用

格式轉換

我之前是在下面這個網站進行手動轉換的:
https://www.upyun.com/webp

還有一些其他的工具(智圖isparta),當然我們也可以藉助google的官方工具

檢測平臺是否支持webp格式

1.檢測瀏覽器是否支持webp的圖片格式,如果支持,就返回true,否則返回false
function checkWebp() {
    try{
        return (document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0);
    }catch(err) {
        return  false;
    }
}

console.log(checkWebp());
2.來自官網
// check_webp_feature:
//   'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.
//   'callback(feature, result)' will be passed back the detection result (in an asynchronous way!)
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];
}

這裏提供了幾種webp的圖片模式,如果瀏覽器支持webp,那麼圖片的寬高會大於0,從而返回true,否則返回false.

使用方法:

第一個參數feature可以傳 lossy,lossless,alpha,animation中的一個,第一個傳個回調函數。獲取他result。如果支持,返回ture,否則返回false。可以再谷歌和IE下試試,谷歌返回ture,IE返回false

check_webp_feature('lossless',function(feature,result){
    alert(result); //true or false
});
3.加載一張webp圖片,如果可以加載出來,那麼就是支持webp,否則就是不支持。如果支持webp,那麼給html加一個class 叫 webps。
;(function(doc) {

    // 給html根節點加上webps類名
    function addRootTag() {
        doc.documentElement.className += "webps";
    }

    // 判斷是否有webps=A這個cookie
    if (!/(^|;\s?)webps=A/.test(document.cookie)) {
        var image = new Image();

        // 圖片加載完成時候的操作
        image.onload = function() {

            // 圖片加載成功且寬度爲1,那麼就代表支持webp了,因爲這張base64圖是webp格式。如果不支持會觸發image.error方法
            if (image.width == 1) {

                // html根節點添加class,並且埋入cookie
                addRootTag();
                document.cookie = "webps=A; max-age=31536000; domain=58.com";
            }
        };

        // 一張支持alpha透明度的webp的圖片,使用base64編碼
        image.src = 'data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==';
    } else {
        addRootTag();
    }
}(document));

如何使用

1. 純手動

因爲之前的項目需要用到的圖片不是很多,所以我就採用了最傻瓜也是最直接的使用方法,在類中多寫一個webp格式的背景圖樣式:
image
這樣的寫法,對於兼容webp的瀏覽器,會引用下方的webp背景圖,對於不兼容的,則顯示上方jpg格式的圖片。不會因爲兼容問題導致圖片不顯示。

不過這種方法不夠靈活,只針對項目中出現少數大圖需要處理時使用。減少其他配置所浪費的時間。

可以看到下面兩個圖的對比,使用了webp的圖片響應速度還是快樂不少的。

image
image

scss配置

如果項目使用了scss,也可以編輯一個函數類:

@mixin bg($url) {
    background-image: url($url);
    @at-root(with: all) .webps & {
        background-image: url($url + '.webp');
    }
}

應用之後,效果等同於:

.testbg{
    background-image: url(.../test.png);
}
.webps .testbg{
    background-image: url(.../test.webp);
}

可以配合上面webp格式轉換的第三種方法使用。

2. 自動化

可以藉助一些其他工具,進行一些自動化的操作。當然這種適合項目中會有大量圖片的情況。目前遇到的情況用上一種方法是比較簡單方便且快速的。

關於webp的高級使用,後續有時間在進行補充。大家也可以網上搜索,應該會有不少文章介紹。

總結

總之,webp在進行較大圖片的替換方案上,是可以作爲一種解決選擇的。不過由於它的兼容性着實還不是很好。所以想要大規模系統的使用還需繼續觀望並期待它之後的發展。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章