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 hình ảnh JPEG và PNG, thường có kích thước tệp giảm 25–35%. Điều này sẽ làm giảm kích thước trang và cải thiện hiệu suất.

  • YouTube nhận thấy rằng việc chuyển sang hình thu nhỏ WebP giúp trang tải nhanh hơn 10%.
  • Facebook đã giảm 25-35% kích thước tệp đối với tệp JPEG và 80% kích thước tệp PNG khi chuyển sang sử dụng WebP.

WebP là một giải pháp thay thế tuyệt vời cho hình ảnh JPEG, PNG và GIF. Ngoài ra, WebP cung cấp cả nén không tổn hao và có tổn hao. Trong quá trình nén không tổn hao, dữ liệu sẽ không bị mất. Quá trình nén có tổn hao sẽ làm 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ợ WebP Imagemin (gói npm). Trình bổ trợ WebP Imagemin 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ụ xây dựng (ví dụ: Webpack hoặc Gulp), trong khi CLI là lựa chọn phù hợp cho các dự án đơn giản 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, nhưng đố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 (kém nhất) đến 100 (tốt nhất). Bạn nên thử nghiệm với vấn đề này, tìm xem mức độ đánh đổi phù hợp giữa chất lượng hình ảnh và kích thước tệp theo nhu cầu của bạn.

Sử dụng cwebp

Chuyển đổi một tệp bằng chế độ 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 là 50:

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

Chuyển đổi tất cả cá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 trình bổ trợ WebP Imagemin riêng hoặc kết hợp với công cụ xây dựng mà bạn yêu thích (Webpack/Gulp/Grunt/v.v.). Quá trình này thường bao gồm 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ụ xây dựng của bạn. Dưới đây là ví dụ về cách thực hiện việc đó 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 chính Imagemin làm tập lệnh Nút. 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 đó trong 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, thì 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: html <img src="flower.jpg" alt="">

Sau: html <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>, kể cả cách sắp xếp thứ tự tương đối với nhau, đề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 nội dung đa 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ợ đị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> thì trình duyệt sẽ bỏ qua các thẻ mà trình duyệt không hỗ trợ. Do đó, ứng dụng chỉ "thấy" thẻ <img src="flower.jpg" alt=""> và tải hình ảnh đó.

Đọc tiêu đề HTTP Accept

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

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

Việc đọc tiêu đề của yêu cầu này và viết lại phản hồi dựa trên nội dung của yêu cầu có lợi ích là đơ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. Dưới đâ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 đi theo cách này, bạn cần thiết lập tiêu đề phản hồi HTTP Vary để đảm bảo bộ nhớ đệm hiểu được rằng hình ảnh có thể được phân phát với nhiều loại nội dung:

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

Quy tắc ghi lại ở trên sẽ tìm phiên bản WebP của bất kỳ hình ảnh JPEG hoặc PNG nào được yêu cầu. Nếu tìm thấy một phiên bản thay thế WebP, hệ thống sẽ phân phát phiên bản đó với tiêu đề Content-Type thích hợp. Điều này sẽ 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 mình đang được phân phát bằng WebP. Chạy bài kiểm tra hiệu suất Lighthouse (Lighthouse > Options > Performance) và tìm kết quả của bài kiểm tra Phân phát hình ảnh ở định dạng thế hệ tiếp theo. Lighthouse sẽ liệt kê mọi hình ảnh không được phân phát trong WebP.