鑑於之前做的大屏的項目,全屏背景圖過大,傳統的寫法導致頁面渲染過慢,因而非常影響用戶體驗。
除此以外,很多時候在開發過程中會出現很多圖片的情況,圖片過多或大,會直接影響頁面的響應時間,從而導致頁面性能變差。
針對以上,我們可以使用WebP來有效的改善。
關於WebP
WebP格式,谷歌(google)開發的一種旨在加快圖片加載速度的圖片格式。圖片壓縮體積大約只有JPEG的2/3,並能節省大量的服務器寬帶資源和數據空間。
WebP既支持有損壓縮也支持無損壓縮。相較編碼JPEG文件,編碼同樣質量的WebP文件需要佔用更少的計算資源。
優勢
- 圖片體積更小的情況下,圖像質量不變
- 具有alpha透明和動畫特性
- 更優的圖像數據壓縮算法
兼容性
目前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格式的背景圖樣式:
這樣的寫法,對於兼容webp的瀏覽器,會引用下方的webp背景圖,對於不兼容的,則顯示上方jpg格式的圖片。不會因爲兼容問題導致圖片不顯示。
不過這種方法不夠靈活,只針對項目中出現少數大圖需要處理時使用。減少其他配置所浪費的時間。
可以看到下面兩個圖的對比,使用了webp的圖片響應速度還是快樂不少的。
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在進行較大圖片的替換方案上,是可以作爲一種解決選擇的。不過由於它的兼容性着實還不是很好。所以想要大規模系統的使用還需繼續觀望並期待它之後的發展。