Tối ưu ảnh cho tốc độ: WebP, AVIF, srcset và lazy loading đúng chỗ
Ảnh là thứ nặng nhất trên phần lớn trang web Việt, và cũng dễ sửa nhất. Đổi sang WebP hoặc AVIF, phục vụ đúng kích thước theo màn hình, khai width và height, tải chậm ảnh dưới màn hình nhưng tải ngay ảnh lớn đầu trang.

Mở một trang sản phẩm của shop thời trang hay một bài review trên blog Việt, kiểm tab Network của trình duyệt, gần như lần nào ảnh cũng chiếm phần lớn dung lượng tải về. Ảnh chụp từ điện thoại 4–8 MB được tải thẳng lên, hiển thị trong khung 400 điểm ảnh, trên mạng 4G. Đây là chỗ cải thiện tốc độ rẻ nhất: không phải đổi máy chủ, không phải viết lại giao diện. Bài này đi qua bốn việc theo thứ tự tác động: kích thước đúng, định dạng nhẹ, khai kích thước để trang không nhảy, và tải đúng lúc.
Việc 1: đừng gửi ảnh to hơn chỗ hiển thị
Ảnh 4000 × 3000 điểm hiển thị trong khung rộng 360 điểm trên điện thoại là lãng phí khoảng 99% số điểm ảnh. Trình duyệt vẫn tải về toàn bộ, rồi thu nhỏ. Việc đầu tiên là thu nhỏ ảnh về kích thước tối đa thật sự cần:
| Vị trí ảnh | Chiều rộng hiển thị tối đa (thường) | Nên lưu bản lớn nhất |
|---|---|---|
| Ảnh bìa bài viết, banner toàn khổ | 1200–1400 điểm | 1600–2000 điểm (cho màn hình mật độ cao) |
| Ảnh trong thân bài, khung nội dung 700–800 điểm | 800 điểm | 1200–1600 điểm |
| Ảnh sản phẩm chính có phóng to | 600 điểm, phóng to 1200 | 1600 điểm |
| Ảnh thu nhỏ trong lưới sản phẩm | 200–300 điểm | 600 điểm |
| Logo, biểu tượng | Nhỏ | SVG nếu có thể |
Điểm ảnh gấp đôi chiều rộng hiển thị là để màn hình mật độ cao (hầu hết điện thoại hiện nay) hiện sắc nét. Gấp bốn lần trở lên thì gần như không ai thấy khác biệt.
Việc 2: phục vụ nhiều cỡ bằng srcset
Một ảnh 1600 điểm cho màn hình máy tính vẫn thừa với điện thoại. Thuộc tính srcset cho trình duyệt chọn bản vừa đủ:
<img src="/anh/sofa-go-soi-800.webp"
srcset="/anh/sofa-go-soi-400.webp 400w,
/anh/sofa-go-soi-800.webp 800w,
/anh/sofa-go-soi-1600.webp 1600w"
sizes="(max-width: 768px) 100vw, 800px"
width="1600" height="1067"
alt="Sofa gỗ sồi ba chỗ bọc nỉ xám đặt cạnh cửa sổ phòng khách">
sizes cho trình duyệt biết ảnh chiếm bao nhiêu chiều rộng màn hình ở từng khổ, để nó chọn bản trong srcset trước khi tải xong CSS. Viết sizes sai (ví dụ để mặc định 100vw cho ảnh chỉ chiếm một cột nhỏ) làm trình duyệt tải bản to hơn cần thiết. WordPress tự sinh srcset và sizes cho ảnh chèn qua trình soạn thảo; nhiều giao diện mua sẵn lại tự dựng thẻ ảnh và bỏ mất phần này, nên cần kiểm.
Việc 3: chọn định dạng nhẹ
| Định dạng | Dùng cho | So với JPEG cùng chất lượng nhìn | Hỗ trợ trình duyệt |
|---|---|---|---|
| JPEG | Ảnh chụp, khi cần tương thích tuyệt đối | Mốc so sánh | Mọi nơi |
| PNG | Ảnh có nền trong suốt, ảnh chụp màn hình nhiều chữ | Nặng hơn nhiều với ảnh chụp | Mọi nơi |
| WebP | Mặc định cho mọi ảnh web | Nhẹ hơn đáng kể, thường 25–35% | Mọi trình duyệt hiện đại |
| AVIF | Ảnh lớn, nhiều chi tiết, muốn nhẹ tối đa | Thường nhẹ hơn cả WebP | Trình duyệt hiện đại; mã hoá chậm hơn |
| SVG | Logo, biểu tượng, hình vẽ đường nét | Rất nhẹ, sắc ở mọi cỡ | Mọi nơi |
Cách thực tế nhất cho site vừa và nhỏ: WebP cho mọi thứ, chất lượng 75–82. Muốn thêm AVIF thì dùng thẻ <picture> để trình duyệt tự chọn, giữ WebP làm dự phòng. Google Hình ảnh lập chỉ mục được cả WebP lẫn AVIF.
Nén thì có nhiều cách: plugin tự chuyển đổi khi tải lên (WordPress), dịch vụ biến đổi ảnh của CDN, hoặc tự chạy công cụ dòng lệnh trước khi tải lên. Dòng lệnh ví dụ:
cwebp -q 80 -resize 1600 0 anh-goc.jpg -o sofa-go-soi-1600.webp
Việc 4: khai width và height để trang không nhảy
Khi thẻ ảnh không có width và height, trình duyệt không biết trước ảnh cao bao nhiêu. Chữ hiện lên trước, ảnh tải xong thì đẩy chữ xuống: người đọc đang đọc dở thì dòng chữ chạy mất. Đó là một trong những nguyên nhân chính của điểm CLS xấu, xem CLS: trang nhảy khi tải.
Chỉ cần ghi đúng tỉ lệ thật của ảnh, CSS vẫn co giãn được:
img { max-width: 100%; height: auto; }
Trình duyệt dùng tỉ lệ width/height để giữ chỗ trước khi ảnh về. Nhiều trình soạn thảo, plugin trang trình bày (page builder) bỏ mất hai thuộc tính này; kiểm tra mã nguồn trang thật, không chỉ xem trong trình soạn thảo.
Lazy loading: tải chậm ảnh dưới, tải ngay ảnh trên
Tải chậm (lazy loading) nghĩa là ảnh chỉ tải khi người đọc cuộn gần tới. Cách chuẩn là thuộc tính có sẵn của trình duyệt:
<img src="..." loading="lazy" width="800" height="533" alt="...">
Hai lỗi ngược nhau hay gặp:
- Tải chậm cả ảnh đầu trang. Ảnh bìa bài viết, ảnh sản phẩm chính, banner trang chủ thường là phần tử lớn nhất trong khung nhìn đầu tiên, tức phần tử quyết định chỉ số LCP. Gắn
loading="lazy"cho nó làm trình duyệt chờ dựng bố cục xong mới tải, LCP chậm thêm rõ rệt. Nhiều plugin tối ưu tốc độ tự gắn lazy cho mọi ảnh, kể cả ảnh này. - Tải chậm bằng JavaScript tự chế: ảnh thật nằm trong
data-src,srclà ảnh trống 1 điểm. Nếu kịch bản lỗi hoặc Google không cuộn tới, ảnh không bao giờ hiện. Thuộc tính chuẩnloading="lazy"đã đủ, không cần thư viện.
Với ảnh LCP, làm ngược lại: báo trình duyệt ưu tiên tải.
<img src="/anh/bia-1600.webp" fetchpriority="high" width="1600" height="840" alt="...">
Nếu ảnh LCP là ảnh nền đặt bằng CSS (background-image), trình duyệt chỉ phát hiện nó sau khi tải CSS. Chuyển sang thẻ <img> thật, hoặc thêm <link rel="preload" as="image"> trong head.
Trên các nền tảng bán hàng như Haravan, Sapo hay Shopify, ảnh tải lên được CDN của nền tảng tự đổi kích thước và định dạng theo tham số trong địa chỉ ảnh, nên việc của bạn chủ yếu là chọn đúng cỡ trong giao diện (ảnh lưới sản phẩm gọi bản nhỏ, không gọi bản gốc) và tải lên ảnh gốc không quá lớn. Kiểm bằng cách mở một trang danh mục trên điện thoại, xem dung lượng từng ảnh thu nhỏ: nếu mỗi ảnh vẫn vài trăm KB thì giao diện đang gọi bản gốc. Đây là lỗi giao diện phổ biến nhất trên các nền tảng này và sửa được trong tệp mẫu của giao diện.

Ảnh và SEO hình ảnh: đừng đánh đổi
Tối ưu tốc độ không được làm mất những gì Google cần để hiểu ảnh:
- Ảnh nội dung phải là thẻ
<img>cósrcthật, không phải ảnh nền CSS (Google không lập chỉ mục ảnh nền). - Giữ alt mô tả; xem alt ảnh và SEO hình ảnh.
- Tên tệp có nghĩa, không dấu.
- Nếu dùng CDN ảnh ở tên miền khác, đảm bảo robots.txt của tên miền đó không chặn Googlebot-Image.
- Ảnh dùng làm ảnh chia sẻ (Open Graph) và ảnh cho Discover nên có bản rộng ít nhất 1200 điểm; đừng vì tối ưu mà chỉ còn bản 600 điểm. Xem Google Discover.
Đo trước và sau
- Mở PageSpeed Insights cho một trang tiêu biểu (bài viết, sản phẩm), ghi LCP, CLS, tổng dung lượng.
- Xem mục “Phân phát hình ảnh có kích thước phù hợp” và “Phân phát hình ảnh ở định dạng mới” để biết ảnh nào thừa bao nhiêu.
- Sửa theo bốn việc ở trên.
- Đo lại. Chỉ số thực địa (dữ liệu người dùng thật) cần khoảng 28 ngày để cập nhật đầy đủ; số thử nghiệm thì thấy ngay.
Kết hợp với chấm điểm SEO để thấy dung lượng HTML và thời gian phản hồi máy chủ: ảnh nhẹ mà máy chủ chậm thì trang vẫn chậm. Bức tranh tổng ở bài TTFB và Core Web Vitals.
Checklist ảnh
- Thu nhỏ ảnh gốc về tối đa gấp đôi chiều rộng hiển thị.
- Lưu WebP chất lượng 75–82; AVIF qua thẻ picture nếu muốn.
- Có srcset và sizes cho ảnh nội dung lớn.
- Mọi ảnh có width và height đúng tỉ lệ.
- Ảnh dưới màn hình đầu:
loading="lazy". - Ảnh LCP: không lazy, có
fetchpriority="high". - Ảnh nội dung là thẻ img có alt, không phải ảnh nền CSS.
- Logo, biểu tượng dùng SVG.
Hỏi đáp
WebP có làm Google không lập chỉ mục ảnh không?
Không. Google Hình ảnh lập chỉ mục WebP và AVIF bình thường. Điều quan trọng là ảnh nằm trong thẻ img có src thật và không bị robots.txt chặn.
Có nên lazy load mọi ảnh trên trang?
Không. Ảnh lớn nhất ở đầu trang (thường là ảnh bìa hoặc ảnh sản phẩm chính) phải tải ngay, tốt nhất có fetchpriority high. Lazy load ảnh đó làm chỉ số LCP xấu đi.
Chất lượng nén bao nhiêu là vừa?
Với WebP, khoảng 75 đến 82 thường không thấy khác biệt bằng mắt so với ảnh gốc trên màn hình điện thoại, trong khi dung lượng giảm nhiều. Ảnh sản phẩm cần thấy rõ chất liệu có thể để cao hơn một chút.
Ảnh nặng có ảnh hưởng thứ hạng không?
Gián tiếp. Ảnh nặng làm trang chậm, chỉ số Core Web Vitals xấu và người đọc thoát ra. Core Web Vitals là một tín hiệu nhỏ, nhưng trải nghiệm chậm ảnh hưởng tới chuyển đổi rõ hơn nhiều.
Đọc tiếp

Alt ảnh và SEO hình ảnh: viết cho người không nhìn thấy, không phải để nhồi từ khoá
Alt mô tả điều ảnh truyền đạt trong ngữ cảnh trang, bằng một câu ngắn tự nhiên; ảnh trang trí để alt rỗng chứ không bỏ thuộc tính. Ngoài al…

TTFB và Core Web Vitals: con số nào ảnh hưởng thứ hạng, con số nào chỉ để báo cáo
Google dùng ba chỉ số Core Web Vitals đo trên người dùng thật (LCP ≤2,5s, INP ≤200ms, CLS ≤0,1 ở phân vị 75), không dùng điểm Lighthouse. T…

CLS: trang nhảy khi đang đọc, năm nguyên nhân và cách giữ chỗ cho từng thứ
CLS (Cumulative Layout Shift) đo mức nội dung trên trang bị xô lệch bất ngờ khi đang hiển thị. Dưới 0,1 là tốt. Cách sửa chung cho mọi nguy…

WordPress chậm: đo trước khi cài thêm plugin tăng tốc, và năm thủ phạm hay gặp
Phần lớn site WordPress chậm vì máy chủ mất quá lâu để dựng trang (TTFB cao), không phải vì ảnh hay CSS. Đo TTFB trước; nếu cao thì tìm ngu…