srcset và sizes cho phép trình duyệt chọn đúng kích thước ảnh theo thiết bị, tiết kiệm băng thông so với serve ảnh cố định. Bài hướng dẫn 5 bước: tạo biến thể, viết srcset và sizes, element picture, debug và tự động hoá qua WordPress.
Vì sao cần srcset — bài toán ảnh thích ứng
Serve một ảnh 1920×1080 cho mọi thiết bị là lãng phí. Màn hình di động 375px chỉ cần ảnh 750px — tải ảnh 1920px là dùng gấp 4 lần băng thông cần thiết.
srcset cho trình duyệt tự chọn biến thể phù hợp theo khung nhìn — tiết kiệm băng thông và tăng tốc ảnh trên di động.
3 vấn đề srcset giải quyết
- Lãng phí băng thông: di động 4G tải ảnh desktop gây lag và tốn data người dùng.
- LCP chậm trên di động: ảnh lớn hiển thị chậm hơn trên CPU di động phổ thông.
- Storage server: nhiều biến thể nhỏ nhưng tổng dung lượng vẫn nhỏ hơn — vì mỗi người dùng chỉ tải một biến thể.
srcset và tối ưu LCP
srcset đúng giúp trình duyệt chọn ảnh vừa đủ — không quá lớn, không quá nhỏ. Đây là kỹ thuật tác động trực tiếp đến LCP.
Xem thêm tại bài tối ưu LCP.
Kết hợp srcset với lazy load và WebP/AVIF để tối ưu băng thông ảnh toàn diện.
Bước 1 — Tạo biến thể kích thước
Tạo 4–6 biến thể từ ảnh gốc. WordPress mặc định tạo thumbnail (150×150), medium (300), medium_large (768), large (1024).
Thêm kích thước tuỳ chỉnh cho hero và ảnh sản phẩm nếu cần size khác.
Kích thước tuỳ chỉnh trong functions.php
// theme/functions.php
add_image_size('hero-mobile', 750, 420, true);
add_image_size('hero-tablet', 1024, 576, true);
add_image_size('hero-desktop', 1920, 1080, true);
add_image_size('product-thumb-2x', 600, 600, true);
add_image_size('product-detail', 1200, 1200, false);
add_theme_support('post-thumbnails');
Khi nào cần tạo lại biến thể
- Thêm kích thước tuỳ chỉnh trong functions.php.
- Ảnh cũ trong thư viện không tự tạo biến thể mới.
- Cài plugin “Regenerate Thumbnails” và chạy bulk regenerate.
- Test 1 ảnh trước khi chạy hàng loạt.
- Chạy bulk vào giờ thấp điểm — tốn CPU và I/O server.
Quyết định bao nhiêu biến thể
4–5 biến thể là đủ: mobile (375px), tablet (768px), laptop (1280px), desktop (1920px), và tuỳ chọn retina. Trình duyệt tự interpolate — không cần tạo thêm.
Mỗi biến thể thêm chiếm storage server. Với shop nhỏ, 4 biến thể là mức cân bằng tốt.
Bước 2 — Viết srcset và sizes attribute
srcset liệt kê các biến thể với width descriptor (300w, 600w, 1200w). Trình duyệt tự chọn biến thể gần nhất với tích của kích thước khung nhìn và tỷ lệ pixel thiết bị.
Attribute sizes cho trình duyệt biết ảnh chiếm bao nhiêu phần trăm khung nhìn — giúp chọn đúng biến thể trước khi CSS load.
Markup chuẩn
<img src="/product-600.webp"
srcset="/product-300.webp 300w,
/product-600.webp 600w,
/product-900.webp 900w,
/product-1200.webp 1200w"
sizes="(max-width: 480px) 90vw,
(max-width: 768px) 50vw,
33vw"
alt="Sản phẩm"
width="600" height="600"
loading="lazy"
decoding="async">
Cách trình duyệt chọn biến thể
- Khung nhìn di động 375px, sizes “90vw” → kích thước hiệu dụng 337px.
- Trình duyệt tính: 337 × tỷ lệ pixel. iPhone tỷ lệ 3 → cần 1011px.
- Chọn biến thể gần nhất ≥ 1011px: 1200w.
- iPhone tỷ lệ 2 → cần 674px → chọn 900w.
- Desktop 1440px, sizes “33vw” → 475px × 1 → chọn 600w.
Lỗi phổ biến khi viết sizes
Lỗi thường gặp nhất: để mặc định sizes là 100vw — trình duyệt luôn chọn biến thể lớn nhất. Sizes phải phản ánh đúng layout CSS thực tế.
Ảnh grid 3 cột → sizes “33vw”. Ảnh full-width → sizes “100vw”.
Ảnh sidebar cố định → sizes “300px”.
Bước 3 — Element picture cho art direction
Element <picture> cho phép serve ảnh hoàn toàn khác nhau theo thiết bị, không chỉ thay đổi kích thước. Use case điển hình: hero crop ngang trên desktop nhưng crop dọc trên di động.
Art direction — crop khác nhau theo thiết bị
<picture>
<source media="(max-width: 480px)"
srcset="/hero-mobile-portrait.webp 750w"
sizes="100vw">
<source media="(max-width: 1024px)"
srcset="/hero-tablet.webp 1024w"
sizes="100vw">
<img src="/hero-desktop.webp"
srcset="/hero-desktop.webp 1920w, /hero-2x.webp 3840w"
sizes="100vw"
alt="Hero"
width="1920" height="1080"
fetchpriority="high">
</picture>
Format fallback — AVIF, WebP, JPG
<picture>
<source type="image/avif" srcset="/hero.avif">
<source type="image/webp" srcset="/hero.webp">
<img src="/hero.jpg" alt="Hero" width="1920" height="1080">
</picture>
Kết hợp art direction và format fallback
Có thể kết hợp cả hai trong cùng một element <picture>: source theo media cho art direction, đồng thời có type attribute cho format fallback.
Xem so sánh chi tiết WebP và AVIF tại bài WebP vs AVIF.
Debug srcset và tự động hoá qua WordPress
srcset phức tạp và dễ gây lỗi tinh vi — trình duyệt chọn sai biến thể do sizes sai. Kiểm tra qua Chrome DevTools tab Network và Elements.
Quy trình debug từng bước
- Mở DevTools (F12) → tab Network → lọc “Img”.
- Reload trang với throttle “Mobile 4G”.
- Click ảnh trong panel Elements → xem “Current Source” bên phải.
- So sánh với biến thể kỳ vọng theo khung nhìn hiện tại.
- Sai biến thể → attribute
sizescần tính lại.
3 lỗi phổ biến khi debug
- Thiếu sizes → mặc định 100vw: trình duyệt luôn chọn biến thể lớn nhất, lãng phí băng thông.
- width attribute không khớp: srcset “1200w” nhưng
width="600"→ trình duyệt confused, fallback 100vw. - Tỷ lệ pixel 3 trên iPhone Pro: chọn biến thể gấp 3 lần khung nhìn → tải nặng hơn dự kiến. Test cả tỷ lệ thấp và cao.
Công cụ kiểm tra srcset
Dùng extension “Responsive Image Linter” (Chrome) để scan toàn trang và báo ảnh nào thiếu srcset hoặc sizes sai. Giảm thời gian debug thủ công đáng kể.
Hoặc dùng Google PageSpeed Insights → mục “Properly size images” để xem ảnh nào đang load quá lớn so với kích thước hiển thị.
Tự động hoá qua WordPress core
WordPress 4.4+ tự động thêm srcset và sizes cho ảnh trong nội dung qua hàm wp_get_attachment_image_srcset(). Theme gọi hàm này thay vì hard-code thẻ img thủ công.
Hàm helper trong template
<?php
$thumb_id = get_post_thumbnail_id();
$alt = get_post_meta($thumb_id, '_wp_attachment_image_alt', true);
?>
<img src="<?php echo esc_url(wp_get_attachment_image_url($thumb_id, 'large')); ?>"
srcset="<?php echo esc_attr(wp_get_attachment_image_srcset($thumb_id, 'large')); ?>"
sizes="(max-width: 768px) 100vw, 800px"
alt="<?php echo esc_attr($alt); ?>"
width="800" height="600"
fetchpriority="high">
Khi WordPress auto srcset chưa đủ
- Hero 1920px trở lên: cần thêm kích thước tuỳ chỉnh qua
add_image_size(). - Ảnh sản phẩm retina 2400px: WordPress mặc định không tạo kích thước này.
- Art direction (crop khác nhau theo thiết bị): cần
<picture>thủ công.
Image CDN thay thế srcset thủ công
Nếu không muốn quản lý nhiều biến thể kích thước, dùng Image CDN như Cloudflare Polish hoặc BunnyCDN Optimizer. CDN tạo biến thể on-the-fly theo URL parameter — không cần lưu file.
Xem chi tiết tại bài Image CDN — tự động tối ưu và phân phối.
Bài liên quan
srcset là một phần của bộ kỹ thuật tối ưu ảnh. Đọc thêm để build kiến thức đầy đủ.
- Lazy load image — kỹ thuật tải trễ 2026
- WebP vs AVIF — so sánh format ảnh thế hệ mới
- Image CDN — tự động tạo biến thể và phân phối
- Aspect ratio — fix CLS từ ảnh thiếu kích thước
- Fix CLS — tổng hợp nguyên nhân và cách khắc phục
Câu hỏi thường gặp
WordPress auto srcset có đủ tốt không?
Đủ cho khoảng 80% trường hợp. WordPress mặc định tạo medium (300), medium_large (768), large (1024) — phủ di động đến tablet desktop.
Cần thêm kích thước tuỳ chỉnh cho hero 1920+ hoặc ảnh sản phẩm retina 2400px qua add_image_size().
5 biến thể kích thước tốn storage quá — có giải pháp nào?
Có 3 hướng:
- Image CDN: Cloudflare Polish, BunnyCDN Optimizer tạo biến thể on-the-fly, không lưu local.
- Plugin kết hợp WebP: Smush, Imagify giảm tổng dung lượng mỗi biến thể đáng kể.
- Tắt kích thước không dùng:
remove_image_size('medium_large')nếu layout không cần 768px.
Test srcset trên DevTools mobile emulator có đủ không?
Không hoàn toàn. DevTools dùng tỷ lệ pixel cố định (2 hoặc 3), không phản ánh chính xác thiết bị thật.
Test trên iPhone/Android thật nếu site ưu tiên di động.
Hoặc dùng BrowserStack cloud emulator để test đa thiết bị mà không cần thiết bị vật lý.
Element picture vs img + srcset — khi nào chọn cái nào?
img + srcset: khi chỉ cần biến thể kích thước khác nhau của cùng một ảnh.
picture: khi cần art direction (crop khác nhau theo thiết bị) hoặc format fallback (AVIF/WebP/JPG). Có thể kết hợp — picture bao ngoài, img bên trong có srcset riêng.
Ảnh trong WooCommerce product gallery cần srcset không?
Có. WooCommerce product gallery dùng wp_get_attachment_image() — WordPress tự thêm srcset.
Cần đảm bảo kích thước ảnh trong gallery đã tạo đúng và sizes attribute phản ánh layout gallery thực tế.
Ảnh zoom (lightbox) thường cần kích thước lớn hơn — kiểm tra plugin gallery có hỗ trợ srcset không.
Cần tối ưu ảnh toàn diện cho site WordPress? Web22 cung cấp dịch vụ tối ưu Core Web Vitals — bao gồm audit srcset, lazy load và cấu hình CDN.


