1. 為什麼用 webp?
科技部落格 GigaOM 曾報導:YouTube 的視訊略縮圖採用 WebP 格式後,網頁載入速度提升了 10%;谷歌的 Chrome 網上應用商店採用 WebP 格式圖片後,每天可以節省幾 TB 的頻寬,頁面平均載入時間大約減少 1/3;Google+ 移動應用採用 WebP 圖片格式後,每天節省了 50TB 資料儲存空間。
同樣的質量下,更小的體積,更快的載入速度。
為什麼不用?
阻止我們用webp大概出於兩個考慮
(1)與JPG相比較,解碼速度慢1.5倍
很多效能的瓶頸在於傳輸的速度,而不是解碼的速度 (這也是固態硬碟對電腦提升明顯的原因),
縮短的載入時間遠遠大於解碼所需要的時間。
參考自 探究WebP一些事兒 測試demo
(2)相容問題
2. webp相容問題
webp的相容性不是很樂觀,尤其在ios safari上一片紅。 這裡我們在客戶端用js檢測是否支援WebP,支援請求webp圖片,不支援保持原格式。
下面是Google官方提供的檢測程式碼 可以檢測 瀏覽器對 webp lossy 有損 lossless無損 alpha透明 animation動圖的支援
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的有損格式就行
(function check_webp_support() {
var _KEY = "lvtou_ifSupportWebp";
var ifCheckAlready = window.localStorage[_KEY];
if (ifCheckAlready) {
return ifCheckAlready;
} else {
check_webp_feature("lossy", function(feature, result) {
//localStorage只能儲存字串
window.localStorage[_KEY] = result ? 'true' : 'false';
});
}
})();
複製程式碼
3. 使用方法
檢測到支援後,把圖片的連結改成webp的就行
我們公司用七牛雲做cdn。 七牛使用webp比較簡單,只要在原來請求的連結後面拼接上一些引數就行。
原連結 196kb
http://www.***.com/test.jpg
webp連結 30.4kb
http://www.***.com/test.jpg?imageMogr2/format/webp
拼接的引數 可以用七牛雲的圖片樣式精簡,這裡不做展開,官方有視訊教程。
4. 懶載入 lazysizes
圖片是網頁中流量佔比最多的部分, 不在可視區域的圖片是沒必要發起請求的。
一般都會做懶載入,我用的是 lazysizes。
lazysizes的使用比較簡單,引入之後,不需要初始化。 把需要懶載入的圖片加上lazyload的class,再 data-src 儲存src就行。
<img data-src="image.jpg" class="lazyload" />
複製程式碼
webp和lazysizes結合,只需要 在 lazysizes 提供了的生命週期鉤子函式裡修改data-src的值就行。
lazybeforeunveil是把data-src替換成src之前的鉤子。
document.addEventListener("lazybeforeunveil", function(e) {
var IMG = e.target;
var src = IMG.getAttribute("data-src");
if (window.lvtou_ifSupportWebp) {
IMG.setAttribute("data-src", src + "?imageMogr2/format/webp");
}
});
複製程式碼
5.IntersectionObserver
傳統判斷圖片是否在可視區域的辦法是
監聽 scroll 事件,在 scroll 的時候,
比較目標元素的 offsetTop來判斷,
scroll事件觸發很頻繁(一般都會做節流) ,獲取offsetTop的值又會觸發重排,很容易引發卡頓。
應運而生的 IntersectionObserver api 可以在,
不監聽scroll和觸發重排的情況下
判斷圖片是否進入可視區。 感興趣的可以看看 阮一峰大佬 的 教程
6. 圖片載入導致的頁面抖動
... 待更新..
7.最終結果
整站webp之後 ,請求小了一半,不錯的提升。... ...
最後我們公司在舉辦活動,對攝影,楹聯文化,和傳統服飾有興趣的朋友 可以去 微信公眾號 看看