Giới thiệu định dạng WebP
WebP là một định dạng ảnh mới do Google phát triển, hỗ trợ nén mất dữ liệu, nén không mất dữ liệu và độ trong suốt; kích thước tệp sau khi nén nhỏ hơn JPEG, PNG và các định dạng khác. Vì vậy, nó có thể tiết kiệm băng thông, giảm thời gian tải trang và tiết kiệm lưu lượng dữ liệu cho người dùng.
Ứng dụng Android và iOS chỉ cần tích hợp thư viện giải mã do Google cung cấp là có thể dễ dàng hỗ trợ định dạng WebP. Tuy nhiên, trên web, WebP vẫn chưa được hỗ trợ rộng rãi, theo Dữ liệu của Can I Use,hiện chỉ có trình duyệt Chrome, Opera và WebView trên Android hỗ trợ WebP. Nhưng ảnh WebP có nhiều ưu điểm như vậy, liệu chúng ta có thể dùng chúng trên trang web không? Có thể. Bài viết này sẽ bàn về vấn đề đó.
Chuyển ảnh hiện có sang định dạng WebP
Để sử dụng định dạng WebP, bạn cần tạo một phiên bản WebP cho tất cả hình ảnh được dùng trên trang web của mình. Nếu bạn sử dụng nhà cung cấp dịch vụ CDN, họ thường cung cấp tùy chọn chuyển mã sang định dạng WebP. Ví dụ như Upyun:

Sau khi thêm cấu hình như vậy, chúng ta có thể sử dụng phiên bản tài nguyên ở định dạng WebP bằng cách thêm hậu tố tương ứng vào URL ảnh.
Bạn cũng có thể dùng plugin của webpack, gulp để chuyển đổi định dạng hình ảnh hàng loạt. Ở đây không trình bày thêm.
Sử dụng định dạng WebP trong trình duyệt
Vì không phải trình duyệt nào cũng hỗ trợ định dạng WebP, chúng ta có hai hướng tiếp cận:một là chỉ dùng định dạng WebP trên các trình duyệt hỗ trợ WebP;hai là khiến các trình duyệt không hỗ trợ WebP có thể hỗ trợ WebP.

Cách thứ nhất: <picture>thẻ
<picture>là một thẻ mới trong HTML5, tương tự<video>Nó cũng có thể chỉ định tài nguyên ở nhiều định dạng để trình duyệt lựa chọn định dạng mình hỗ trợ rồi tải.
<picture class="picture"> <source type="image/webp" srcset="image.webp"> <img class="image" src="image.jpg"> </picture>
Nếu trình duyệt hỗ trợ định dạng WebP, nó sẽ tải image.webp,nếu không sẽ tải image.jpg。
Ngay cả khi trình duyệt không hỗ trợ<picture>thẻ, hình ảnh vẫn hiển thị bình thường, chỉ là CSS có thể không chọn đúng được picture phần tử. Ví dụ trong IE8, CSS dưới đây sẽ không có tác dụng:
.picture img { width: 100px; height: 100px;
}Nhưng có thể viết kiểu hiển thị cho hình ảnh như sau:
.image { width: 100px; height: 100px;
}Ngay cả khi trình duyệt sử dụng ảnh định dạng WebP, cuối cùng vẫn sẽ áp dụng img kiểu dáng của phần tử.
Tuy nhiên, chỉ cần đã sử dụng html5shiv,giúp trình duyệt cũ hỗ trợ thẻ này, nhờ đó bộ chọn CSS có thể hoạt động bình thường.
Phương pháp này đơn giản nhất, nhưng không áp dụng được cho hình ảnh trong CSS(chẳng hạn ảnh nền).
Cách hai:Dùng JS thay thế URL của ảnh.
Nhiều trang của chúng ta thường sử dụng tính năng “tải lười” cho hình ảnh——thông thường là đặt URL của hình ảnh vào img trong một thuộc tính tùy chỉnh của phần tử, sau đó dùng JS gán URL cho thuộc tính sau vào thời điểm thích hợp:src thuộc tính. Theo nguyên lý tương tự, tùy việc trình duyệt có hỗ trợ định dạng WebP hay không, chúng ta có thể gán cho img phần tử mang lại những khác biệt src giá trị.
Trước hết, chúng ta cần dùng JS để xác định trình duyệt có hỗ trợ định dạng WebP hay không, bằng cách đưa cho trình duyệt một ảnh WebP và xem nó có hiển thị chính xác không. Cách này chạy bất đồng bộ, nên cần viết các thao tác tiếp theo trong hàm gọi lại. Chúng ta có thể lưu kết quả vào localStorage vào trong, như vậy sau này sẽ không cần kiểm tra lại nữa.
function checkWebp(callback) { var img = new Image();
img.onload = function () { var result = (img.width > 0) && (img.height > 0);
callback(result);
};
img.onerror = function () {
callback(false);
};
img.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA';
}Sau đó dùng đoạn mã dưới đây để thay thế src tương ứng tùy theo việc có hỗ trợ WebP hay không.
function showImage(useWebp){ var imgs = Array.from(document.querySelectorAll('img'));
imgs.forEach(function(i){ var src = i.attributes['data-src'].value; if (useWebp){
src = src.replace(/\.jpg$/, '.webp');
}
i.src = src;
});
}
checkWebp(showImage);Ưu điểm của cách này là có thể kết hợp với hàm tải lười hiện có. Hơn nữa, dùng JS, chúng ta còn có thể xử lý hình ảnh trong CSS(như ảnh nền, v.v.).
Cách thứ ba:Dùng JS giải mã ảnh WebP
Vì bộ giải mã WebP là mã nguồn mở, vậy có thể dùng JS để triển khai không? Tất nhiên là được,Đã có người viết bộ giải mã WebP bằng JS。Việc tích hợp thư viện JS này có nghĩa là dùng JS giải mã tất cả ảnh WebP rồi chuyển đổi thành base64,sau đó thay thế URL ban đầu, như vậy trình duyệt vốn không hỗ trợ WebP cũng có thể hiển thị WebP bình thường. Thư viện này rất dễ sử dụng, chỉ cần xem hướng dẫn trên trang web.
Nhược điểm của cách này là vì JS phải giải mã ảnh WebP nên cần gửi yêu cầu bất đồng bộ tới URL trong src tại đây(tuy nhiên, do ảnh đã được tải trước đó một lần nên sẽ dùng ngay bộ nhớ đệm); hơn nữa, JS giải mã khá chậm, ảnh hưởng đến hiệu năng, có thể phải chờ một lúc ảnh mới hiển thị.
Trên đây là một số cách sử dụng ảnh WebP trong trình duyệt, bạn có thể lựa chọn tùy tình hình thực tế. Trong quá trình áp dụng, sau khi sử dụng định dạng WebP, dung lượng ảnh nhìn chung giảm hơn 1/3, vừa tăng tốc độ tải vừa tiết kiệm lưu lượng dữ liệu cho người dùng. Chúng tôi rất khuyến khích bắt đầu sử dụng định dạng này ngay từ bây giờ.