Hỗ trợ trình duyệt
Bạn có thể sử dụng thuộc tính loading
để tải từng phần hình ảnh mà không cần
viết mã tải từng phần tuỳ chỉnh hoặc sử dụng một thư viện JavaScript riêng. Sau đây là một
bản minh hoạ tính năng:
Trang này trình bày chi tiết cách triển khai tính năng tải từng phần trong trình duyệt.
Tại sao có thể tải từng phần ở cấp trình duyệt?
Theo HTTP Archive, hình ảnh là loại thành phần được yêu cầu nhiều nhất cho hầu hết các trang web và chúng thường chiếm nhiều băng thông hơn bất kỳ tài nguyên nào khác. Ở phân vị thứ 90, các trang web gửi hơn 5 MB hình ảnh trên máy tính và thiết bị di động.
Trước đây, có 2 cách để trì hoãn việc tải hình ảnh ngoài màn hình:
- Sử dụng API Intersection Observer
- Sử dụng trình xử lý sự kiện
scroll
,resize
hoặcorientationchange
Một trong hai tuỳ chọn này có thể cho phép nhà phát triển đưa vào hành vi tải từng phần, và nhiều nhà phát triển đã xây dựng thư viện của bên thứ ba để cung cấp các thành phần trừu tượng dễ sử dụng hơn nữa.
Tuy nhiên, với tính năng tải từng phần được trình duyệt hỗ trợ trực tiếp, bạn không cần thư viện bên ngoài. Tính năng tải từng phần ở cấp trình duyệt cũng đảm bảo rằng quá trình tải hình ảnh vẫn hoạt động ngay cả khi ứng dụng tắt JavaScript. Tuy nhiên, lưu ý rằng việc tải chỉ bị trì hoãn khi JavaScript được bật.
Thuộc tính loading
Chrome tải hình ảnh ở những mức độ ưu tiên khác nhau tuỳ thuộc vào vị trí đặt hình ảnh so với khung nhìn của thiết bị. Hình ảnh bên dưới khung nhìn được tải bằng mức độ ưu tiên thấp hơn nhưng chúng vẫn được tìm nạp khi trang tải.
Bạn có thể dùng thuộc tính loading
để trì hoãn việc tải ngoài màn hình hoàn toàn
hình ảnh:
<img src="image.png" loading="lazy" alt="…" width="200" height="200">
Sau đây là những giá trị được hỗ trợ cho thuộc tính loading
:
lazy
: Hoãn tải tài nguyên cho đến khi tài nguyên đó đến khoảng cách tính toán từ khung nhìn.eager
: Hành vi tải mặc định của trình duyệt, giống với bao gồm thuộc tính và có nghĩa là hình ảnh sẽ được tải bất kể hình ảnh đó nằm ở đâu trên trang. Đây là giá trị mặc định, nhưng bạn nên đặt nếu công cụ của bạn tự động thêmloading="lazy"
khi không có giá trị rõ ràng hoặc nếu công cụ tìm lỗi mã nguồn của bạn phàn nàn nếu không được đặt rõ ràng.
Mối quan hệ giữa thuộc tính loading
và mức độ ưu tiên tìm nạp
Giá trị eager
là một lệnh để tải hình ảnh như bình thường mà không trì hoãn
sẽ tải thêm nếu hình ảnh nằm ngoài màn hình. Không tải được hình ảnh nhanh hơn
so với một hình ảnh khác không có thuộc tính loading
.
Nếu bạn muốn tăng mức độ ưu tiên tìm nạp cho một hình ảnh quan trọng (ví dụ:
hình ảnh LCP), sử dụng Mức độ ưu tiên tìm nạp với
fetchpriority="high"
.
Hình ảnh có loading="lazy"
và fetchpriority="high"
vẫn bị trễ khi
nó nằm ngoài màn hình, sau đó được tìm nạp với mức độ ưu tiên cao khi gần như nằm trong
khung nhìn. Sự kết hợp này không thực sự cần thiết vì trình duyệt sẽ
vẫn có thể tải hình ảnh đó với mức độ ưu tiên cao.
Ngưỡng khoảng cách từ khung nhìn
Tất cả hình ảnh có thể xem được ngay lập tức mà không cần cuộn trang sẽ tải như bình thường. Hình ảnh phía dưới khung nhìn của thiết bị chỉ được tìm nạp khi người dùng cuộn gần chúng.
Quá trình triển khai tính năng tải từng phần của Chromium cố gắng đảm bảo rằng các hình ảnh ngoài màn hình được tải đủ sớm để chúng tải xong trước thời điểm người dùng cuộn cho chúng bằng cách tìm nạp kỹ trước khi chúng hiển thị trong khung nhìn.
Ngưỡng khoảng cách sẽ thay đổi tuỳ thuộc vào các yếu tố sau:
- Loại tài nguyên hình ảnh đang được tìm nạp
- Loại kết nối hiệu quả
Bạn có thể tìm thấy giá trị mặc định cho các loại kết nối hiệu quả khác nhau trong nguồn Chromium. Bạn có thể thử nghiệm với các ngưỡng khác nhau này bằng cách điều tiết mạng trong Công cụ cho nhà phát triển.
Cải thiện khả năng tiết kiệm dữ liệu và ngưỡng khoảng cách từ khung nhìn
Vào tháng 7 năm 2020, Chrome đã thực hiện các điểm cải tiến quan trọng để điều chỉnh ngưỡng khoảng cách từ khung nhìn của hình ảnh tải từng phần nhằm đáp ứng tốt hơn kỳ vọng của nhà phát triển.
Trên kết nối nhanh (4G), chúng tôi đã giảm ngưỡng khoảng cách từ khung nhìn của Chrome từ 3000px
xuống 1250px
và trên các kết nối chậm hơn (3G trở xuống), đã thay đổi ngưỡng này từ 4000px
thành 2500px
. Thay đổi này đạt được hai mục đích:
<img loading=lazy>
có hành vi gần hơn với trải nghiệm do các thư viện tải từng phần JavaScript cung cấp.- Các ngưỡng mới về khoảng cách từ khung nhìn vẫn có nghĩa là hình ảnh có thể sẽ được tải vào thời điểm người dùng cuộn đến.
Bạn có thể xem bảng so sánh giữa ngưỡng khoảng cách từ khung nhìn cũ và ngưỡng mới cho một trong các bản minh hoạ của chúng tôi về kết nối nhanh (4G) tiếp theo:
và các ngưỡng mới so với LazySizes (một thư viện JavaScript tải từng phần phổ biến):
Cung cấp các thuộc tính kích thước hình ảnh
Mặc dù trình duyệt tải hình ảnh, trình duyệt không biết ngay
trừ khi chúng được chỉ định rõ ràng. Để cho phép trình duyệt đặt trước
đủ không gian trên trang cho hình ảnh và tránh thay đổi bố cục gây gián đoạn,
bạn nên thêm các thuộc tính width
và height
vào tất cả các thẻ <img>
.
<img src="image.png" loading="lazy" alt="…" width="200" height="200">
Ngoài ra, bạn có thể chỉ định giá trị của chúng trực tiếp theo kiểu cùng dòng:
<img src="image.png" loading="lazy" alt="…" style="height:200px; width:200px;">
Phương pháp hay nhất về việc đặt phương diện sẽ áp dụng cho thẻ <img>
bất kể
cho dù bạn đang tải từng phần, nhưng tải từng phần có thể khiến quá trình tải trở nên quan trọng hơn.
Tính năng tải từng phần trong Chromium được triển khai theo cách giúp hình ảnh tăng khả năng
được tải ngay khi chúng xuất hiện, nhưng vẫn có khả năng
nhưng chúng sẽ không tải vào đúng thời điểm. Trong trường hợp đó, việc không chỉ định width
và
height
trên hình ảnh của bạn làm tăng tác động của chúng đến Điểm số tổng hợp về mức thay đổi bố cục. Nếu
bạn không thể chỉ định hình ảnh của mình các phương diện, tải từng phần có thể tiết kiệm mạng
có nguy cơ chịu việc thay đổi bố cục gia tăng này.
Trong hầu hết các trường hợp, hình ảnh vẫn sẽ tải từng phần nếu bạn không chỉ định kích thước, nhưng
có một số trường hợp hiếm gặp mà bạn cần lưu ý. Không có width
và height
được chỉ định, kích thước hình ảnh được mặc định là 0×0 pixel. Nếu bạn có thư viện
hình ảnh, trình duyệt có thể quyết định rằng tất cả hình ảnh đó vừa với khung nhìn ở
vì mỗi hình ảnh không chiếm dung lượng và không có hình ảnh nào bị đẩy ra khỏi màn hình. Trong
trong trường hợp này, trình duyệt quyết định tải mọi thứ, khiến trang tải nhiều hơn
từ từ.
Để xem ví dụ về cách loading
hoạt động với một số lượng lớn hình ảnh, hãy tham khảo
bản minh hoạ này.
Bạn cũng có thể tải từng phần hình ảnh mà bạn đã xác định bằng phần tử <picture>
:
<picture>
<source media="(min-width: 800px)" srcset="large.jpg 1x, larger.jpg 2x">
<img src="photo.jpg" loading="lazy">
</picture>
Mặc dù trình duyệt sẽ quyết định hình ảnh nào cần tải từ bất kỳ <source>
nào
bạn chỉ cần thêm loading
vào phần tử <img>
dự phòng.
Hình ảnh luôn tải nhanh hiển thị trong khung nhìn đầu tiên
Đối với những hình ảnh xuất hiện khi người dùng tải trang lần đầu tiên và đặc biệt đối với hình ảnh LCP, hãy dùng chế độ tải nhanh theo mặc định của trình duyệt để các hình ảnh này có thể xuất hiện ngay lập tức. Để biết thêm thông tin, hãy xem bài viết Ảnh hưởng về hiệu suất khi tải từng phần quá nhiều.
Chỉ sử dụng loading=lazy
cho hình ảnh bên ngoài khung nhìn ban đầu. Trình duyệt
không thể tải từng phần một hình ảnh cho đến khi biết được vị trí của hình ảnh trên trang,
khiến chúng tải chậm hơn.
<!-- visible in the viewport -->
<img src="product-1.jpg" alt="..." width="200" height="200">
<img src="product-2.jpg" alt="..." width="200" height="200">
<img src="product-3.jpg" alt="..." width="200" height="200">
<!-- offscreen images -->
<img src="product-4.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-5.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-6.jpg" loading="lazy" alt="..." width="200" height="200">
Xuống cấp nhẹ
Những trình duyệt không hỗ trợ thuộc tính loading
sẽ bỏ qua thuộc tính này. Họ sẽ không nhận được
lợi ích của tính năng tải từng phần, nhưng việc thêm tính năng này sẽ không có tác động tiêu cực.
Câu hỏi thường gặp
Một số câu hỏi thường gặp về tính năng tải từng phần ở cấp trình duyệt.
Tôi có thể tự động tải từng phần hình ảnh trong Chrome không?
Trước đây, Chromium tự động tải từng phần bất kỳ hình ảnh nào phù hợp
bị trì hoãn nếu chế độ Lite
đã được bật trên Chrome dành cho Android và thuộc tính loading
không được bật
được cung cấp hoặc đặt thành loading="auto"
. Tuy nhiên,
Chế độ thu gọn và loading="auto"
đã ngừng hoạt động
và hiện chưa có kế hoạch cung cấp tính năng tự động tải từng phần hình ảnh trong Chrome.
Tôi có thể thay đổi khoảng cách để hình ảnh ở gần khung nhìn trước khi tải không?
Các giá trị này được cố định giá trị trong mã và không thể thay đổi thông qua API. Tuy nhiên, chúng có thể thay đổi trong tương lai khi các trình duyệt thử nghiệm với ngưỡng khác nhau khoảng cách và biến.
Hình nền CSS có thể sử dụng thuộc tính loading
không?
Không, bạn chỉ có thể sử dụng với thẻ <img>
.
loading
có thể làm việc với các hình ảnh trong khung nhìn chưa hiển thị ngay không?
Việc sử dụng loading="lazy"
có thể ngăn việc tải hình ảnh khi bạn không tải hình ảnh
hiển thị nhưng nằm trong khoảng cách đã tính.
Những hình ảnh này có thể nằm sau một băng chuyền hoặc bị CSS ẩn khỏi một số màn hình nhất định
kích thước. Ví dụ: Chrome, Safari và Firefox không tải hình ảnh bằng
Định kiểu display: none;
, trên phần tử hình ảnh hoặc trên phần tử mẹ
. Tuy nhiên, các kỹ thuật ẩn hình ảnh khác, chẳng hạn như sử dụng opacity:0
định kiểu, nhưng vẫn khiến trình duyệt tải hình ảnh. Luôn kiểm tra
kỹ lưỡng để đảm bảo quảng cáo hoạt động như dự kiến.
Chrome 121 đã thay đổi cách hoạt động của hình ảnh cuộn ngang như băng chuyền. Các tuỳ chọn này hiện sử dụng cùng một ngưỡng như cuộn dọc. Điều này có nghĩa là đối với trường hợp sử dụng băng chuyền, hình ảnh sẽ được tải trước khi hiển thị trong khung nhìn. Điều này có nghĩa là người dùng ít có khả năng nhận thấy việc tải hình ảnh, nhưng sẽ làm tăng lượt tải xuống. Sử dụng bản minh hoạ Tải từng phần theo chiều ngang để so sánh hành vi trên Chrome với Safari và Firefox.
Nếu tôi đang sử dụng một thư viện của bên thứ ba hoặc một tập lệnh để tải từng phần hình ảnh thì sao?
Với sự hỗ trợ đầy đủ của tính năng tải từng phần được tích hợp vào các trình duyệt hiện đại, có lẽ bạn sẽ không cần cần một thư viện hoặc tập lệnh của bên thứ ba để tải từng phần hình ảnh.
Một lý do để tiếp tục sử dụng thư viện của bên thứ ba cùng với loading="lazy"
là cung cấp một polyfill cho những trình duyệt không hỗ trợ thuộc tính này hoặc để
có nhiều quyền kiểm soát hơn đối với thời điểm kích hoạt tính năng tải từng phần.
Làm thế nào để xử lý các trình duyệt không hỗ trợ tính năng tải từng phần?
Tính năng tải từng phần hình ảnh ở cấp trình duyệt được hỗ trợ tốt trên tất cả các trình duyệt chính và nên dùng cho hầu hết các trường hợp sử dụng để không cần phải sử dụng thêm các phần phụ thuộc trên JavaScript.
Tuy nhiên, nếu cần hỗ trợ nhiều trình duyệt hơn hoặc muốn có nhiều quyền kiểm soát hơn đối với ngưỡng tải từng phần, bạn có thể sử dụng thư viện của bên thứ ba để tải từng phần hình ảnh trên trang web của mình.
Bạn có thể sử dụng thuộc tính loading
để xác định xem trình duyệt có hỗ trợ
tính năng:
if ('loading' in HTMLImageElement.prototype) {
// supported in browser
} else {
// fetch polyfill/third-party library
}
Ví dụ: lazysizes là
Thư viện JavaScript tải từng phần. Bạn có thể phát hiện loading
có hỗ trợ hay không
để tải lazysizes dưới dạng thư viện dự phòng chỉ khi loading
không
được hỗ trợ. Phương thức này hoạt động như sau:
- Thay thế
<img src>
bằng<img data-src>
để tránh tải nhanh trong các trình duyệt không được hỗ trợ. Nếu thuộc tínhloading
được hỗ trợ, hãy hoán đổidata-src
với giásrc
. - Nếu
loading
không được hỗ trợ, hãy tải một bản dự phòng từ lazysize và bắt đầu phương thức đó bằng cách sử dụng lớplazyload
để cho biết cần tải từng phần hình ảnh nào:
<!-- Let's load this in-viewport image normally -->
<img src="hero.jpg" alt="…">
<!-- Let's lazy-load the rest of these images -->
<img data-src="unicorn.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="cats.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="dogs.jpg" alt="…" loading="lazy" class="lazyload">
<script>
if ('loading' in HTMLImageElement.prototype) {
const images = document.querySelectorAll('img[loading="lazy"]');
images.forEach(img => {
img.src = img.dataset.src;
});
} else {
// Dynamically import the LazySizes library
const script = document.createElement('script');
script.src =
'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.2/lazysizes.min.js';
document.body.appendChild(script);
}
</script>
Sau đây là bản minh hoạ về mẫu này. Hãy thử tính năng này trong trình duyệt cũ để xem tính năng dự phòng trong thực tế.
Tính năng tải từng phần cho iframe có được hỗ trợ trong trình duyệt không?
Hỗ trợ trình duyệt
<iframe loading=lazy>
cũng đã được chuẩn hoá. Thao tác này cho phép bạn tải từng phần iframe bằng loading
. Để biết thêm thông tin, hãy xem bài viết Đã đến lúc tải từng phần iframe ngoài màn hình!
Tính năng tải từng phần ở cấp trình duyệt ảnh hưởng như thế nào đến quảng cáo trên trang web?
Tất cả quảng cáo hiển thị cho người dùng dưới dạng hình ảnh hoặc iframe tải từng phần giống như bất kỳ quảng cáo nào khác hình ảnh hoặc iframe.
Google xử lý hình ảnh như thế nào khi in một trang web?
Tất cả hình ảnh và iframe đều tải ngay lập tức khi trang được in. Xem vấn đề #875403 để biết chi tiết.
Lighthouse có nhận ra tính năng tải từng phần ở cấp trình duyệt không?
Lighthouse 6.0 và yếu tố cao hơn phương pháp tải từng phần hình ảnh ngoài màn hình có thể sử dụng các ngưỡng khác nhau, cho phép họ truyền Kiểm tra Hoãn phát hình ảnh ngoài màn hình.
Tải từng phần hình ảnh để cải thiện hiệu suất
Trình duyệt hỗ trợ tính năng tải từng phần hình ảnh có thể giúp bạn thực hiện việc này dễ dàng hơn rất nhiều để cải thiện hiệu suất cho các trang của bạn hiệu suất.
Bạn có nhận thấy hành vi bất thường nào khi tính năng này được bật trong Chrome không? Báo cáo lỗi!