Tải trước hình ảnh thích ứng

Ngày xuất bản: 30 tháng 9 năm 2019, Ngày cập nhật gần đây nhất: 10 tháng 7 năm 2026

Bạn có thể tải trước hình ảnh thích ứng, nhờ đó hình ảnh có thể tải nhanh hơn đáng kể bằng cách giúp trình duyệt xác định đúng hình ảnh từ srcset trước khi hiển thị thẻ img.

Tổng quan về hình ảnh thích ứng

Browser Support

  • Chrome: 73.
  • Edge: 79.
  • Firefox: 78.
  • Safari: 17.2.

Source

Giả sử bạn đang duyệt web trên màn hình rộng 300 pixel và trang yêu cầu hình ảnh rộng 1500 pixel. Trang đó đã lãng phí rất nhiều dữ liệu di động của bạn vì màn hình của bạn không thể làm gì với tất cả độ phân giải bổ sung đó. Lý tưởng nhất là trình duyệt sẽ tìm nạp một phiên bản hình ảnh chỉ rộng hơn một chút so với kích thước màn hình, ví dụ: 325 pixel. Điều này đảm bảo hình ảnh có độ phân giải cao mà không lãng phí dữ liệu, đồng thời giúp hình ảnh tải nhanh hơn.

Hình ảnh thích ứng cho phép trình duyệt tìm nạp các tài nguyên hình ảnh khác nhau cho các thiết bị khác nhau. Nếu bạn không sử dụng CDN hình ảnh, hãy lưu nhiều kích thước cho mỗi hình ảnh và chỉ định các kích thước đó trong thuộc tính srcset. Giá trị w cho trình duyệt biết chiều rộng của mỗi phiên bản để trình duyệt có thể chọn phiên bản phù hợp cho mọi thiết bị:

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="…">

Tổng quan về tính năng tải trước

Browser Support

  • Chrome: 50.
  • Edge: 79.
  • Firefox: 85.
  • Safari: 11.1.

Source

Tính năng tải trước cho phép bạn thông báo cho trình duyệt về các tài nguyên quan trọng mà bạn muốn tải càng sớm càng tốt, trước khi các tài nguyên đó được phát hiện trong HTML. Điều này đặc biệt hữu ích đối với những tài nguyên không dễ khám phá, chẳng hạn như phông chữ có trong biểu định kiểu, hình nền hoặc tài nguyên được tải từ tập lệnh.

<link rel="preload" as="image" href="important.png" fetchpriority="high">

imagesrcset và imagesizes

Phần tử <link> sử dụng các thuộc tính imagesrcset và imagesizes để tải trước hình ảnh thích ứng. Sử dụng các thuộc tính này cùng với <link rel="preload">, với cú pháp srcset và sizes được dùng trong phần tử <img>.

Ví dụ: nếu bạn muốn tải trước một hình ảnh thích ứng được chỉ định bằng:

 <img src="wolf.jpg" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw" alt="A rad wolf">

Bạn có thể làm việc đó bằng cách thêm đoạn mã sau vào phần <head> của HTML:

<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw" fetchpriority="high">

Thao tác này sẽ bắt đầu một yêu cầu bằng cách sử dụng cùng một logic lựa chọn tài nguyên mà srcset và sizes sử dụng.

Trường hợp sử dụng

Sau đây là một số trường hợp sử dụng để tải trước hình ảnh thích ứng.

Tải trước hình ảnh thích ứng được chèn động

Hãy tưởng tượng bạn đang tải hình ảnh chính một cách linh động trong một bản trình chiếu và bạn biết hình ảnh nào sẽ xuất hiện đầu tiên. Trong trường hợp đó, có thể bạn muốn hiển thị hình ảnh đó càng sớm càng tốt và không đợi tập lệnh trình chiếu tải hình ảnh đó.

Bạn có thể kiểm tra vấn đề này trên một trang web có thư viện hình ảnh được tải linh động:

  1. Mở bản minh hoạ trình chiếu này trong một thẻ mới.
  2. Nhấn Control+Shift+J (hoặc Command+Option+J trên máy Mac) để mở Công cụ cho nhà phát triển.
  3. Nhấp vào thẻ Mạng.
  4. Trong danh sách thả xuống Throttling (Điều tiết), hãy chọn Fast 3G (3G nhanh).
  5. Bỏ đánh dấu hộp Tắt bộ nhớ đệm.
  6. Tải lại trang.
Bảng điều khiển Mạng của Chrome DevTools cho thấy một thác nước có tài nguyên JPEG chỉ bắt đầu tải xuống sau một số JavaScript.
Nếu không tải trước, hình ảnh sẽ bắt đầu tải sau khi trình duyệt chạy xong tập lệnh. Đối với hình ảnh đầu tiên, độ trễ đó là không cần thiết.

Việc sử dụng preload ở đây cho phép hình ảnh bắt đầu tải trước thời hạn, nhờ đó, hình ảnh có thể sẵn sàng hiển thị khi trình duyệt cần hiển thị hình ảnh đó.

Bảng điều khiển Mạng của Chrome DevTools cho thấy một biểu đồ thác nước với tài nguyên JPEG đang tải xuống song song với một số JavaScript.
Việc tải trước hình ảnh đầu tiên cho phép hình ảnh bắt đầu tải cùng lúc với tập lệnh.

Để xem sự khác biệt mà tính năng tải trước mang lại, hãy kiểm tra cùng một thư viện hình ảnh được tải linh động nhưng có hình ảnh đầu tiên được tải trước bằng cách làm theo các bước trong ví dụ đầu tiên.

Tải trước hình nền bằng cách sử dụng nhóm hình ảnh

Nếu có nhiều hình nền cho các mật độ màn hình khác nhau, bạn có thể chỉ định các hình nền đó trong CSS bằng cú pháp image-set. Sau đó, trình duyệt có thể chọn hình ảnh để hiển thị dựa trên DPR của màn hình.

background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);

Vấn đề với hình nền CSS là trình duyệt chỉ phát hiện ra chúng sau khi đã tải xuống và xử lý tất cả CSS trong <head> của trang.

Bạn có thể kiểm tra vấn đề này trên một trang web mẫu có hình nền thích ứng.

Bảng điều khiển Mạng của Chrome DevTools cho thấy một Thác nước có tài nguyên JPEG chỉ bắt đầu tải xuống sau một số CSS.
Trong ví dụ này, quá trình tải hình ảnh xuống sẽ không bắt đầu cho đến khi CSS được tải xuống hoàn toàn, gây ra độ trễ không cần thiết cho việc hiển thị hình ảnh.

Tính năng tải trước hình ảnh thích ứng giúp bạn tải những hình ảnh đó nhanh hơn.

<link rel="preload" as="image" imagesrcset="cat.png 1x, cat-2x.png 2x" fetchpriority="high">

Việc bỏ qua thuộc tính href giúp đảm bảo rằng các trình duyệt không hỗ trợ imagesrcset trên phần tử <link> nhưng hỗ trợ image-set trong CSS sẽ tải đúng nguồn xuống. Tuy nhiên, trong trường hợp này, họ sẽ không được hưởng lợi từ việc tải trước.

Bạn có thể kiểm tra cách hoạt động của ví dụ trước bằng hình nền thích ứng được tải trước trong bản minh hoạ tải trước nền thích ứng.

Bảng điều khiển Mạng của Chrome DevTools cho thấy một Thác nước có tài nguyên JPEG đang tải xuống song song với một số CSS.
Tại đây, hình ảnh và CSS bắt đầu tải xuống cùng một lúc, giúp hình ảnh tải nhanh hơn.

Hiệu quả thực tế của việc tải trước hình ảnh thích ứng

Về lý thuyết, việc tải trước hình ảnh thích ứng có thể giúp tăng tốc độ tải hình ảnh, nhưng trên thực tế thì sao?

Để trả lời câu hỏi đó, tôi đã tạo hai bản sao của một cửa hàng PWA minh hoạ: một bản sao không tải trước hình ảnh, và một bản sao tải trước một số hình ảnh. Vì trang web tải chậm hình ảnh bằng JavaScript, nên trang web có thể hưởng lợi từ việc tải trước những hình ảnh xuất hiện trong khung nhìn ban đầu.

Thử nghiệm này cho ra kết quả sau đây đối với trường hợp không tải trước và tải trước hình ảnh:

  • Bắt đầu kết xuất vẫn giữ nguyên.
  • Speed Index cải thiện một chút (273 mili giây, vì hình ảnh đến nhanh hơn không chiếm một phần lớn diện tích pixel).
  • Last Painted Hero (Phần tử chính cuối cùng được hiển thị) đã cải thiện đáng kể, thêm 1,2 giây.
Bản so sánh cuộn phim WebPageTest cho thấy hình ảnh được tải trước hiển thị nhanh hơn khoảng 1,5 giây.
Hình ảnh sẽ xuất hiện nhanh hơn đáng kể khi được tải trước, giúp cải thiện đáng kể trải nghiệm người dùng.

Tải trước và <picture>

Nhóm công tác về hiệu suất web đang thảo luận về việc thêm một giá trị tương đương cho thuộc tính preload cho srcset và sizes, nhưng không phải phần tử <picture>, phần tử xử lý trường hợp sử dụng "chỉ đạo nghệ thuật".

Vẫn còn một số vấn đề kỹ thuật cần giải quyết để tải trước <picture>, nhưng trong thời gian chờ đợi, bạn có thể áp dụng các giải pháp sau:

<picture>
    <source srcset="small_cat.jpg" media="(max-width: 400px)">
    <source srcset="medium_cat.jpg" media="(max-width: 800px)">
    <img src="large_cat.jpg">
</picture>

Logic lựa chọn nguồn hình ảnh của phần tử <picture> sẽ xem xét các thuộc tính media của phần tử <source> theo thứ tự, tìm phần tử đầu tiên khớp và sử dụng tài nguyên đính kèm.

Vì tính năng tải trước thích ứng không có khái niệm "thứ tự" hoặc "kết quả khớp đầu tiên", nên bạn sẽ cần dịch các điểm ngắt thành một nội dung như sau:

<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)" fetchpriority="high">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)" fetchpriority="high">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)" fetchpriority="high">

Tải trước và type

Phần tử <picture> cũng hỗ trợ so khớp trên type đầu tiên, để bạn có thể cung cấp nhiều định dạng hình ảnh, nhờ đó trình duyệt có thể chọn định dạng hình ảnh đầu tiên mà trình duyệt hỗ trợ.

Trường hợp sử dụng này chỉ được hỗ trợ một phần khi tải trước: trình duyệt chỉ nên tải trước các loại được hỗ trợ. Vì vậy, bạn có thể sử dụng thuộc tính này để ngăn trình duyệt tải trước các loại mimetype không được hỗ trợ bằng cách đưa thuộc tính này vào lệnh tải trước:

<link rel="preload" href="image.avif" type="image/avif" as="image" fetchpriority="high">

Tuy nhiên, không giống như <picture>, phương thức này sẽ không dừng lại ở loại được hỗ trợ đầu tiên. Vì vậy, nếu có nhiều lượt tải trước cho nhiều loại, thì tất cả hình ảnh sẽ được tải trước:

Không nên làm điều này – tải trước nhiều loại:

<link rel="preload" href="image.avif" type="image/avif" as="image" fetchpriority="high">
<link rel="preload" href="image.jpg" type="image/jpg" as="image" fetchpriority="high">

Thay vào đó, hãy làm như sau – tải trước loại ưu tiên nhất:

<link rel="preload" href="image.avif" type="image/avif" as="image" fetchpriority="high">

Việc tải trước định dạng mới nhất (AVIF trong trường hợp này) đóng vai trò là một cải tiến tăng dần, trong đó các trình duyệt hỗ trợ loại đó sẽ được hưởng lợi và các trình duyệt khác sẽ không được hưởng lợi từ việc tải trước.

Đối với những trang web mà hình ảnh có thể được phát hiện nhanh chóng trong HTML, bạn nên tránh tải trước và thay vào đó, hãy để trình quét tải trước lấy hình ảnh từ các phần tử <picture> và <source>. Dù sao thì đây cũng là một phương pháp hay nhất, đặc biệt là khi sử dụng Mức độ ưu tiên tìm nạp để giúp ưu tiên hình ảnh phù hợp, vì phương pháp này cho phép tải trước hình ảnh chính xác dựa trên khả năng hỗ trợ của trình duyệt. Việc này cũng giúp loại bỏ nguy cơ tải trước bị lỗi thời so với mã đánh dấu chính khi hình ảnh hoặc trang thay đổi.

Ảnh hưởng đến Nội dung lớn nhất hiển thị (LCP)

Vì hình ảnh có thể là ứng cử viên cho Nội dung lớn nhất hiển thị (LCP), nên việc tải trước hình ảnh có thể cải thiện LCP của trang web.

Bất kể hình ảnh bạn đang tải trước có thích ứng hay không, thì việc tải trước sẽ hoạt động hiệu quả nhất khi không thể tìm thấy tài nguyên hình ảnh trong tải trọng đánh dấu ban đầu. Bạn cũng sẽ thấy LCP cải thiện nhiều hơn trên các trang web hiển thị mã đánh dấu ở phía máy khách so với các trang web gửi mã đánh dấu hoàn chỉnh từ máy chủ.