Một ảnh rộng 1920 điểm ảnh trên trang sẽ được người dùng điện thoại tải về đủ cả, rồi mới thu xuống 390 điểm ảnh trên màn hình — tốn gấp năm lần băng thông và trang chậm đi vô ích. srcset cho phép trình duyệt chọn phiên bản hợp với màn hình, miễn là bạn đã tạo sẵn các phiên bản đó.

Vì sao một ảnh duy nhất là không đủ

Chỉ số LCP trong Core Web Vitals thường chính là tấm ảnh lớn ở đầu trang. Phục vụ điện thoại một file 1920 rộng nặng 400KB thì LCP khó xuống dưới 2,5 giây; bản 480 rộng nặng 40KB trên cùng đường truyền nhanh hơn cả một bậc độ lớn. Tín hiệu trải nghiệm trang của Google đọc trực tiếp con số này.

Ngược lại, ảnh rộng 768 trên màn hình desktop lớn sẽ bị mờ. Vì thế cần nhiều kích thước, để trình duyệt tự chọn.

Bảng breakpoint thực dụng

Các mốc kích thước cho ảnh responsive
Mốc kích thước bám theo chiều rộng của nội dung, không phải chiều rộng màn hình

Breakpoint bám theo chiều rộng ảnh được hiển thị trên trang, chứ không phải viewport. Với hai trường hợp phổ biến là banner toàn chiều rộng và ảnh minh họa trong bài:

  • Ảnh toàn chiều rộng (hero, banner): 480, 768, 1200, 1920. Tương ứng điện thoại, máy tính bảng, laptop, màn hình lớn.
  • Ảnh trong bài viết (cột nội dung tới khoảng 800): 400, 800, 1200; bản 1200 phục vụ màn hình 1,5x–2x.
  • Ảnh thu nhỏ và thẻ card (hiển thị khoảng 300): 300 và 600.

Nhiều bậc hơn không có nghĩa là tốt hơn. Mỗi bậc là thêm một lần xuất và thêm một file phải lưu, mà trình duyệt vốn chịu được độ lệch, nên các bậc cách nhau 1,5–2 lần là điểm ngọt. Bốn bậc phủ hơn chín trong mười tổ hợp thiết bị.

Có cần bản 2x không?

Màn hình Retina và hầu hết điện thoại chạy ở mật độ 2x–3x; ảnh hiển thị rộng 400 cần tới 800 điểm ảnh mới sắc nét. Những bậc lớn hơn trong bảng đã đóng vai bản 2x của các bậc nhỏ — 768 là 2x cho điện thoại rộng 390, 1200 là 2x cho cột rộng 600.

Nên không cần một bộ “@2x” riêng. Giữ khoảng cách các bậc chừng 2 lần, trình duyệt sẽ tự chọn bậc cao hơn theo mật độ màn hình.

Định dạng: WebP trước, JPG dự phòng

Ở cùng chất lượng, WebP nhỏ hơn JPG 25–35 phần trăm và mọi trình duyệt hiện đại đều hỗ trợ. Xuất WebP ở từng kích thước và giữ bản JPG dự phòng qua phần tử picture cho trình duyệt cũ; nếu khán giả của bạn không còn dùng trình duyệt trước 2020, chỉ cần WebP là đủ.

AVIF còn nhỏ hơn nữa nhưng mã hóa trong trình duyệt chậm hơn nhiều, gây khó khi chạy lô lớn. AVIF so với WebP và JPEG phân tích kỹ các đánh đổi này.

Xuất hàng loạt cả bộ

Thả ảnh gốc vào Xử lý ảnh hàng loạt rồi chạy một lần cho mỗi bậc, mỗi lần đổi chiều rộng và hậu tố:

  1. Kích thước: chiều rộng 480, tắt Cho phép phóng to ảnh nhỏ, xuất WebP chất lượng 80 phần trăm, hậu tố -480.
  2. Giữ nguyên thiết lập, đổi sang 768 với hậu tố -768; rồi 1200; rồi 1920.
  3. Muốn có bản JPG dự phòng, đổi đầu ra sang JPG, giữ nguyên các hậu tố và chạy lại.

Mỗi lượt chạy chỉ vài giây, và file ZIP đã chứa sẵn hero-480.webp, hero-768.webp và các file tương tự, sẵn sàng bỏ vào thư mục ảnh. Hãy để tắt Cho phép phóng to ảnh nhỏ để ảnh gốc 1000 điểm ảnh không bao giờ bị kéo giãn lên 1920.

Muốn xem sự chênh lệch dung lượng ở từng bậc trên một ảnh, thử Đổi kích thước ảnh với một file đơn lẻ.

Viết HTML

Với ảnh toàn chiều rộng:

<img src="hero-1200.jpg"
     srcset="hero-480.webp 480w, hero-768.webp 768w, hero-1200.webp 1200w, hero-1920.webp 1920w"
     sizes="100vw" width="1920" height="1080" alt="...">

Với ảnh trong bài, đặt sizes theo chiều rộng thật, ví dụ sizes="(max-width: 840px) 100vw, 800px". Luôn khai báo width và height để trình duyệt giữ chỗ trước và trang không bị nhảy.

Xong phần này, hãy bổ sung lời khuyên về lazy loading và nén ảnh trong cách làm ảnh tải nhanh hơn, và phần ảnh trong điểm hiệu năng của bạn gần như đã đạt tối đa.