Image SEO

Image decoding

Quá trình giải mã dữ liệu hình ảnh thành pixel hiển thị, có thể tối ưu bằng thuộc tính decoding="async" để không chặn render.

6 lượt xem Cập nhật: 30/05/2026

Image decoding là gì?

Image decoding (giải mã hình ảnh) là quá trình trình duyệt chuyển dữ liệu hình ảnh đã nén (như JPEG, PNG, WebP) thành các pixel có thể hiển thị trên màn hình. Đây là bước bắt buộc sau khi tải xong tệp hình ảnh, nhưng trước khi hình ảnh hiện ra cho người dùng. Quá trình này tiêu tốn tài nguyên CPU và có thể làm chậm việc vẽ lại trang (paint), đặc biệt với hình ảnh lớn hoặc nhiều hình cùng lúc.

Tại sao quan trọng trong SEO?

Image decoding ảnh hưởng trực tiếp đến chỉ số Core Web Vitals — đặc biệt là Largest Contentful Paint (LCP)Interaction to Next Paint (INP). Nếu trình duyệt phải đợi giải mã hình ảnh quan trọng (ví dụ: banner đầu trang) trước khi render nội dung chính, LCP sẽ bị kéo dài. Google coi LCP > 2,5 giây là kém, và điều này làm giảm khả năng xếp hạng trên kết quả tìm kiếm.

Ngoài ra, hình ảnh không được giải mã kịp thời còn gây hiện tượng 'flash of unstyled content' (FOUC) nhẹ, làm trải nghiệm người dùng giật cục — yếu tố gián tiếp ảnh hưởng đến tỷ lệ thoát và thời gian ở lại trang, cả hai đều là tín hiệu hành vi mà Google sử dụng trong đánh giá chất lượng trang.

Cách hoạt động

Theo mặc định, trình duyệt giải mã hình ảnh đồng bộ (synchronous): nó tạm dừng việc vẽ lại trang để hoàn tất giải mã từng hình theo thứ tự xuất hiện trong DOM. Với hình ảnh lớn hoặc nhiều hình nằm gần phần đầu trang (above-the-fold), điều này gây tắc nghẽn render.

Thuộc tính decoding="async" cho phép trình duyệt giải mã hình ảnh không đồng bộ — nghĩa là nó có thể tiếp tục render nội dung văn bản, layout và các phần khác trong khi hình ảnh đang được giải mã nền. Kết quả: trang hiển thị nhanh hơn, LCP cải thiện rõ rệt.

Lưu ý: decoding="async" chỉ áp dụng cho thẻ <img>, không hỗ trợ trên thẻ <picture> hay CSS background-image. Giá trị hợp lệ của thuộc tính này là sync (mặc định), async, hoặc auto (tùy trình duyệt quyết định — hiện chưa được hỗ trợ rộng rãi).

Hướng dẫn thực hiện

Để tối ưu image decoding, bạn chỉ cần thêm thuộc tính decoding="async" vào các thẻ <img> không cần hiển thị ngay lập tức — đặc biệt là hình ảnh dưới màn hình cuộn (below-the-fold), hình ảnh trong tab ẩn, hoặc hình ảnh phụ trợ như icon nhỏ, avatar người dùng.

  1. Xác định hình ảnh không cần ưu tiên: Dùng công cụ DevTools → Tab “Network” → lọc theo “Img”, sắp xếp theo kích thước hoặc vị trí trong DOM. Những hình có loading="lazy" thường phù hợp để đặt decoding="async".
  2. Thêm thuộc tính vào thẻ <img>:
    <img src="product.jpg" alt="Sản phẩm A" loading="lazy" decoding="async" width="300" height="200">
  3. Không áp dụng cho hình ảnh quan trọng đầu trang: Hình ảnh trong LCP candidate (ví dụ: hero banner, logo, ảnh sản phẩm chính) nên giữ decoding="sync" (hoặc không khai báo gì cả) để đảm bảo giải mã nhanh và chính xác — tránh hiện tượng render sai màu hoặc mất chi tiết do giải mã không đầy đủ.
  4. Kết hợp với các kỹ thuật khác: Dùng fetchpriority="low" cho hình ảnh không quan trọng; nén định dạng WebP/AVIF; đặt đúng width/height để tránh layout shift.

Lỗi thường gặp

  • Áp dụng decoding="async" cho tất cả hình ảnh: Gây hiện tượng hình ảnh bị mờ, nhòe hoặc không hiển thị đúng ở một số trình duyệt cũ (đặc biệt là Safari phiên bản <16.4). Khắc phục: Chỉ dùng cho hình ảnh không nằm trong LCP và đã kiểm thử trên đa trình duyệt.
  • Thiếu thuộc tính width/height khi dùng decoding="async": Dẫn đến layout shift vì trình duyệt không biết kích thước trước khi giải mã xong. Khắc phục: Luôn khai báo kích thước rõ ràng hoặc dùng CSS aspect-ratio.
  • Sử dụng decoding="async" trên hình ảnh SVG: Không có tác dụng — SVG là vector, không cần giải mã pixel. Thuộc tính này chỉ ảnh hưởng đến raster image (JPEG, PNG, WebP…). Khắc phục: Loại trừ SVG khỏi quy tắc áp dụng.

Ví dụ thực tế

Một trang danh mục sản phẩm có 20 hình ảnh sản phẩm, trong đó 3 hình đầu tiên là LCP candidates. Sau khi đo LCP bằng PageSpeed Insights, nhóm phát triển nhận thấy thời gian giải mã chiếm 320ms trong tổng 2.8s. Họ áp dụng:

  • decoding="async" cho 17 hình còn lại (có kèm loading="lazy" và đúng width/height)
  • Giữ nguyên decoding="sync" cho 3 hình đầu
  • Kết hợp nén WebP và lazy-load

Kết quả sau 7 ngày theo dõi qua CrUX: LCP trung bình giảm từ 2.81s xuống 1.94s (giảm 31%), tỷ lệ người dùng trải nghiệm 'good' tăng từ 42% lên 76%. Không ghi nhận lỗi hiển thị trên Chrome, Edge, Firefox và Safari 16.4+.

Câu hỏi thường gặp

decoding="async" có tương thích với mọi trình duyệt?

Không. Hỗ trợ đầy đủ từ Chrome 78+, Edge 79+, Firefox 69+, Safari 16.4+. Trên Safari <16.4, thuộc tính bị bỏ qua (không gây lỗi nhưng cũng không có hiệu lực). Bạn nên kiểm tra qua caniuse.com và dùng feature detection nếu cần thiết.

Có nên dùng decoding="async" kết hợp với loading="eager"?

Không khuyến khích. loading="eager" bắt trình duyệt tải ngay hình ảnh — thường là hình quan trọng đầu trang. Việc ép giải mã không đồng bộ có thể làm chậm thời điểm hiển thị thực tế, gây hại cho LCP. Chỉ dùng decoding="async" với loading="lazy" hoặc khi chắc chắn hình ảnh không ảnh hưởng đến LCP.

decoding="async" có thay thế được việc tối ưu định dạng hình ảnh?

Không. Đây là hai lớp tối ưu độc lập: định dạng (WebP/AVIF) giảm kích thước tệp; decoding="async" tối ưu cách xử lý tệp sau khi tải. Cả hai cần dùng song song để đạt hiệu quả cao nhất. Việc chỉ dùng một trong hai sẽ bỏ lỡ tối ưu tiềm năng.

Thuộc tính Mục đích Ảnh hưởng đến LCP Ghi chú
decoding="async" Giải mã nền, không chặn render Giảm nhẹ (nếu áp dụng đúng) Chỉ hiệu quả với hình ảnh below-the-fold
loading="lazy" Trì hoãn tải hình ảnh ngoài vùng nhìn Không ảnh hưởng trực tiếp (có thể làm LCP tệ hơn nếu LCP candidate bị lazy) Luôn kiểm tra LCP candidate trước khi áp dụng
fetchpriority="low" Giảm mức độ ưu tiên tải Giảm nhẹ nếu hình ảnh không phải LCP Hỗ trợ từ Chrome 101+, không có trên Safari
width/height Ngăn layout shift Cải thiện trực tiếp (giảm CLS → hỗ trợ LCP gián tiếp) Bắt buộc khi dùng lazy-load hoặc decoding="async"