Sử dụng hình ảnh WebP

Katie Hempenius
Katie Hempenius

Tại sao bạn nên quan tâm?

Hình ảnh WebP nhỏ hơn so với các hình ảnh JPEG và PNG tương ứng, thường ở mức giảm kích thước tệp từ 25 đến 35%. Điều này làm giảm kích thước trang và cải thiện hiệu suất.

WebP là một định dạng thay thế tuyệt vời cho hình ảnh JPEG, PNG và GIF. Ngoài ra, WebP cung cấp cả tính năng nén không tổn hao và có tổn hao. Trong phương thức nén không suy hao, dữ liệu sẽ không bị mất. Phương thức nén có tổn hao giúp giảm kích thước tệp, nhưng có thể làm giảm chất lượng hình ảnh.

Chuyển đổi hình ảnh sang WebP

Mọi người thường sử dụng một trong những phương pháp sau để chuyển đổi hình ảnh sang WebP: công cụ dòng lệnh cwebp hoặc trình bổ trợ Imagemin WebP (gói npm). Trình bổ trợ Imagemin WebP thường là lựa chọn tốt nhất nếu dự án của bạn sử dụng tập lệnh bản dựng hoặc công cụ bản dựng (ví dụ: Webpack hoặc Gulp), trong khi CLI là lựa chọn phù hợp cho các dự án nhỏ hoặc nếu bạn chỉ cần chuyển đổi hình ảnh một lần.

Khi chuyển đổi hình ảnh sang WebP, bạn có thể đặt nhiều chế độ cài đặt nén. Tuy nhiên, đối với hầu hết mọi người, điều duy nhất bạn cần quan tâm là chế độ cài đặt chất lượng. Bạn có thể chỉ định mức chất lượng từ 0 (thấp nhất) đến 100 (cao nhất). Bạn nên thử nghiệm để tìm ra mức độ phù hợp giữa chất lượng hình ảnh và kích thước tệp cho nhu cầu của mình.

Sử dụng cwebp

Chuyển đổi một tệp bằng cách sử dụng chế độ cài đặt nén mặc định của cwebp:

cwebp images/flower.jpg -o images/flower.webp

Chuyển đổi một tệp duy nhất, sử dụng mức chất lượng 50:

cwebp -q 50 images/flower.jpg -o images/flower.webp

Chuyển đổi tất cả tệp trong một thư mục:

for file in images/*; do cwebp "$file" -o "${file%.*}.webp"; done

Sử dụng Imagemin

Bạn có thể sử dụng riêng trình bổ trợ Imagemin WebP hoặc sử dụng cùng với công cụ xây dựng mà bạn yêu thích (Webpack/Gulp/Grunt/v.v.). Việc này thường liên quan đến việc thêm khoảng 10 dòng mã vào tập lệnh bản dựng hoặc tệp cấu hình cho công cụ bản dựng. Sau đây là ví dụ về cách thực hiện việc này cho Webpack, GulpGrunt.

Nếu không sử dụng một trong các công cụ xây dựng đó, bạn có thể sử dụng Imagemin dưới dạng một tập lệnh Node. Tập lệnh này sẽ chuyển đổi các tệp trong thư mục images và lưu các tệp đó vào thư mục compressed_images.

const imagemin = require('imagemin');
const imageminWebp = require('imagemin-webp');

imagemin(['images/*'], {
  destination: 'compressed_images',
  plugins: [imageminWebp({quality: 50})]
}).then(() => {
  console.log('Done!');
});

Phân phát hình ảnh WebP

Nếu trang web của bạn chỉ hỗ trợ các trình duyệt tương thích với WebP, bạn có thể dừng đọc. Nếu không, hãy phân phát WebP cho các trình duyệt mới hơn và hình ảnh dự phòng cho các trình duyệt cũ:

Trước:

<img src="flower.jpg" alt="">

Sau:

<picture>
  <source type="image/webp" srcset="flower.webp">
  <source type="image/jpeg" srcset="flower.jpg">
  <img src="flower.jpg" alt="">
</picture>

Các thẻ <picture>, <source><img>, bao gồm cả cách sắp xếp các thẻ này tương ứng với nhau, tất cả đều tương tác để đạt được kết quả cuối cùng này.

<picture>

Thẻ <picture> cung cấp một trình bao bọc cho 0 hoặc nhiều thẻ <source> và một thẻ <img>.

<source>

Thẻ <source> chỉ định một tài nguyên phương tiện.

Trình duyệt sử dụng nguồn được liệt kê đầu tiên ở định dạng mà trình duyệt hỗ trợ. Nếu không hỗ trợ bất kỳ định dạng nào được liệt kê trong thẻ <source>, trình duyệt sẽ quay lại tải hình ảnh do thẻ <img> chỉ định.

<img>

Thẻ <img> giúp mã này hoạt động trên các trình duyệt không hỗ trợ thẻ <picture>. Nếu không hỗ trợ thẻ <picture>, trình duyệt sẽ bỏ qua các thẻ không được hỗ trợ. Do đó, trình duyệt chỉ "nhìn thấy" thẻ <img src="flower.jpg" alt=""> và tải hình ảnh đó.

Đọc tiêu đề Accept HTTP

Nếu có phần phụ trợ ứng dụng hoặc máy chủ web cho phép bạn ghi lại các yêu cầu, bạn có thể đọc giá trị của tiêu đề Accept HTTP. Tiêu đề này sẽ quảng cáo các định dạng hình ảnh thay thế được hỗ trợ:

Accept: image/webp,image/svg+xml,image/*,*/*;q=0.8

Việc đọc tiêu đề yêu cầu này và viết lại phản hồi dựa trên nội dung của tiêu đề sẽ giúp đơn giản hoá việc đánh dấu hình ảnh. Mã đánh dấu <picture> có thể khá dài với nhiều nguồn. Sau đây là quy tắc mod_rewrite của Apache có thể phân phát các phiên bản thay thế WebP:

RewriteEngine On
RewriteCond %{HTTP:Accept} image/webp [NC]
RewriteCond %{HTTP:Content-Disposition} !attachment [NC]
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f [NC]
RewriteRule (.+)\.(png|jpe?g)$ $1.webp [T=image/webp,L]

Nếu chọn cách này, bạn cần đặt tiêu đề phản hồi HTTP Vary để đảm bảo bộ nhớ đệm hiểu rằng hình ảnh có thể được phân phát theo cách khác nhau tuỳ thuộc vào tiêu đề Accept:

<FilesMatch ".(jpe?g|png)$">
  <IfModule mod_headers.c>
    Header set Vary "Accept"
  </IfModule>
</FilesMatch>

Quy tắc viết lại trước đó sẽ tìm kiếm phiên bản WebP của mọi hình ảnh JPEG hoặc PNG được yêu cầu. Nếu tìm thấy một phiên bản thay thế WebP, thì phiên bản đó sẽ được phân phát bằng tiêu đề Content-Type thích hợp. Điều này cho phép bạn sử dụng mã đánh dấu hình ảnh tương tự như sau với tính năng hỗ trợ WebP tự động:

<img src="flower-320w.jpg" srcset="flower-320w.jpg 320w, flower-640w.jpg 640w, flower-960w.jpg 960w">

Xác minh việc sử dụng WebP

Bạn có thể dùng Lighthouse để xác minh rằng tất cả hình ảnh trên trang web của bạn đều được phân phát bằng WebP. Chạy quy trình kiểm tra hiệu suất của Lighthouse (Lighthouse > Options > Performance (Lighthouse > Tuỳ chọn > Hiệu suất)) và tìm kết quả của quy trình kiểm tra Phân phát hình ảnh ở định dạng thế hệ mới. Lighthouse sẽ liệt kê mọi hình ảnh không được phân phát ở định dạng WebP.