Bạn có thể tải trước hình ảnh thích ứng để hình ảnh tải nhanh hơn đáng kể bằng cách giúp trình duyệt xác định chính xác hình ảnh từ srcset
trước khi hiển thị thẻ img
.
Tổng quan về hình ảnh thích ứng
Hỗ trợ trình duyệt
Giả sử bạn đang duyệt web trên màn hình có chiều rộng 300 pixel và trang yêu cầu hình ảnh có chiều rộng 1500 pixel. Trang đó đã lãng phí rất nhiều dữ liệu di động vì màn hình của bạn không thể làm gì với tất cả độ phân giải thừa đó. 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 kích thước màn hình một chút, 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 và 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 nhiều tài nguyên hình ảnh cho nhiều thiết bị. 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 từng 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
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 ngay khi có thể, 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 các tài nguyên không dễ phát hiện, chẳng hạn như phông chữ có trong các tệp đị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">
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 phần tử 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 nội dung sau vào <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">
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ẽ hiển thị trước tiên. Trong trường hợp đó, bạn nê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 động:
- Mở bản minh hoạ trình chiếu này trong một thẻ mới.
- Nhấn
Control+Shift+J
(hoặcCommand+Option+J
trên máy Mac) để mở DevTools. - Nhấp vào thẻ Mạng.
- Trong danh sách thả xuống Throttling (Giới hạn), hãy chọn Fast 3G (3G nhanh).
- Tắt hộp đánh dấu Tắt bộ nhớ đệm.
- Tải lại trang.
Việc sử dụng preload
ở đây cho phép hình ảnh bắt đầu tải trước, vì vậy, 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 đó.
Để 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 động nhưng đã tải trước hình ảnh đầu tiên 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 image-set
Nếu có nhiều hình nền cho nhiều mật độ màn hình, 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 một trong các tỷ lệ khung hì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 được các hình nền đó 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.
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">
Việc bỏ qua thuộc tính href
cho phép bạn đả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 nguồn chính xác xuống. Tuy nhiên, họ sẽ không được hưởng lợi từ tính năng tải trước trong trường hợp này.
Bạn có thể kiểm tra cách ví dụ trước hoạt động với hình nền thích ứng được tải trước trong bản minh hoạ tải trước hình nền thích ứng.
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 hình ảnh, nhưng 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 cửa hàng không tải trước hình ảnh, và một cửa hàng tải trước một số hình ảnh. Vì trang web tải từng phần hình ảnh bằng JavaScript, nên bạn 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.
Điều đó đã tạo ra các kết quả sau đây cho không tải trước và cho tải trước hình ảnh:
- Start Render (Bắt đầu kết xuất) vẫn giữ nguyên.
- Chỉ số tốc độ cải thiện một chút (273 mili giây, vì hình ảnh đến nhanh hơn không chiếm nhiều pixel).
- Last Painted Hero cải thiện đáng kể, tăng 1,2 giây.
Tải trước và <picture>
Nhóm làm việc về hiệu suất web đang thảo luận về việc thêm một tính năng tải trước tương đương cho srcset
và sizes
, nhưng không phải phần tử <picture>
. Phần tử này xử lý trường hợp sử dụng "hướng dẫn 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ẽ lần lượt xem xét các thuộc tính media
của phần tử <source>
, tìm thuộc tính đầ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 "khớp đầu tiên", nên bạn sẽ cần dịch các điểm ngắt thành những nội dung như sau:
<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)">
Tải trước và type
Phần tử <picture>
cũng hỗ trợ so khớp trên type
đầu tiên, cho phép bạn cung cấp nhiều định dạng hì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 không được hỗ trợ tính năng tải trước.
Đối với các trang web sử dụng tính năng so khớp kiểu, bạn nên tránh tải trước và thay vào đó, hãy để trình quét tải trước chọn hình ảnh từ các phần tử <picture>
và <source>
. Dù sao, đây cũng là 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.
Ảnh hưởng đến Thời gian hiển thị nội dung lớn nhất (LCP)
Vì hình ảnh có thể là thành phần đề xuất cho chỉ số Thời gian hiển thị nội dung lớn nhất (LCP), nên việc tải trước hình ảnh có thể cải thiện chỉ số 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, tính năng tải trước sẽ hoạt động tốt nhất khi tài nguyên hình ảnh không được phát hiện trong tải trọng đánh dấu ban đầu. Bạn cũng sẽ cải thiện được nhiều hơn về LCP trên những trang web hiển thị mã đánh dấu ở phía máy khách so với những trang web gửi mã đánh dấu hoàn chỉnh từ máy chủ.