Tính năng tải từng phần tích hợp sẵn cuối cùng cũng đã ra mắt!
Hỗ trợ cấp trình duyệt cho hình ảnh tải từng phần hiện được hỗ trợ trên web! Video này cho thấy bản minh hoạ tính năng này:
Bạn có thể sử dụng thuộc tính loading
để tải từng phần của hình ảnh mà không cần viết mã tải từng phần tuỳ chỉnh hay sử dụng một thư viện JavaScript riêng. Hãy cùng tìm hiểu chi tiết.
Khả năng tương thích với trình duyệt
Những trình duyệt không hỗ trợ thuộc tính loading
sẽ bỏ qua thuộc tính đó mà không gây ra tác dụng phụ.
Tại sao lại 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 đối với hầu hết các trang web và 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. Có rất nhiều hình ảnh mèo.
Trước đây, có hai cách trì hoãn việc tải hình ảnh ngoài màn hình:
- Sử dụng Intersection Observer API
- Sử dụng trình xử lý sự kiện
scroll
,resize
hoặcorientationchange
Mỗi lựa chọn đều có thể cho phép nhà phát triển thêm chức năng tải từng phần. Đồng thời, 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 tính năng trừu tượng dễ sử dụng hơn. 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 phải có 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 tính năng tải chậm của hình ảnh vẫn hoạt động ngay cả khi JavaScript bị tắt trên ứng dụng.
Thuộc tính loading
Chrome tải hình ảnh ở các mức độ ưu tiên khác nhau tuỳ thuộc vào vị trí của hình ảnh tương ứng với khung nhìn của thiết bị. Hình ảnh bên dưới khung nhìn được tải với mức độ ưu tiên thấp hơn nhưng vẫn được tìm nạp khi trang tải.
Bạn có thể sử dụng thuộc tính loading
để trì hoãn hoàn toàn việc tải hình ảnh ngoài màn hình mà bạn truy cập bằng cách cuộn:
<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 đạt đến khoảng cách đã tính từ khung nhìn.eager
: Hành vi tải mặc định của trình duyệt, tức là không bao gồm thuộc tính này và có nghĩa là hình ảnh sẽ được tải bất kể vị trí của hình ảnh trên trang. Mặc dù đây là giá trị mặc định, nhưng bạn nên thiết lập rõ ràng giá trị này nếu công cụ của bạn tự động thêmloading="lazy"
nếu không có giá trị rõ ràng hoặc nếu trình tìm lỗi mã nguồn của bạn khiếu nại nếu công cụ không được thiết lập 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
chỉ là một lệnh tải hình ảnh như bình thường, không trì hoãn quá trình tải thêm nếu hình ảnh nằm ngoài màn hình. Điều này không ngụ ý rằng hình ảnh được tải nhanh hơn một hình ảnh khác không có thuộc tính loading="eager"
.
Các trình duyệt ưu tiên tài nguyên dựa trên nhiều phương pháp phỏng đoán và thuộc tính loading
chỉ nêu thời điểm tài nguyên hình ảnh được đưa vào hàng đợi chứ không phải cách thức tài nguyên được ưu tiên trong hàng đợi đó. eager
chỉ ngụ ý rằng các trình duyệt xếp hàng đợi thông thường sử dụng theo mặc định.
Nếu 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) thì bạn nên sử dụng Tìm nạp mức độ ưu tiên với fetchpriority="high"
.
Xin lưu ý rằng hình ảnh có loading="lazy"
và fetchpriority="high"
sẽ vẫn bị trễ khi nằm ngoài màn hình, sau đó được tìm nạp ở mức độ ưu tiên cao khi gần nằm trong khung nhìn. Trong trường hợp này, hệ thống có thể sẽ tìm nạp với mức độ ưu tiên cao, vì vậy, tổ hợp này không thực sự cần thiết và không cần thiết.
Ngưỡng khoảng cách từ khung nhìn
Tất cả hình ảnh trong màn hình đầu tiên (nghĩa là có thể xem được ngay lập tức mà không cần cuộn) đều tải bình thường. Những thành phần nằm ở phía xa bên dưới khung nhìn của thiết bị chỉ được tìm nạp khi người dùng cuộn đế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 để những hình ảnh đó tải xong khi người dùng cuộn đến gần các hình ảnh đó. Bằng cách tìm nạp tốt các hình ảnh lân cận trước khi chúng hiển thị trong khung nhìn, chúng tôi tối đa hoá khả năng hình ảnh đã được tải vào thời điểm hiển thị.
So với các thư viện tải từng phần của JavaScript, các ngưỡng tìm nạp hình ảnh cuộn vào khung hiển thị có thể được xem là thận trọng.
Ngưỡng khoảng cách là không cố định và thay đổi tuỳ thuộc vào nhiều yếu tố:
- 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 các giá trị mặc định cho các loại kết nối hiệu quả khác nhau trong nguồn Chromium. Những con số này và thậm chí cả phương pháp chỉ tìm nạp khi đạt đến một khoảng cách nhất định từ khung nhìn, có thể thay đổi trong tương lai khi nhóm Chrome cải thiện phương pháp phỏng đoán để xác định thời điểm bắt đầu tải.
Cải thiện khả năng tiết kiệm dữ liệu và các ngưỡng về khoảng cách từ khung nhìn
Kể từ tháng 7 năm 2020, Chrome đã thực hiện những điểm cải tiến đáng kể để điều chỉnh ngưỡng tải từng phần của hình ảnh theo khoảng cách giữa khung nhìn, từ đó đáp ứng tốt hơn kỳ vọng của nhà phát triển.
Đối với các 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 từ 4000px
thành 2500px
. Thay đổi này đạt được hai điều sau:
<img loading=lazy>
hoạt động gần hơn với trải nghiệm do 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 cho phép chúng tôi đảm bảo rằng hình ảnh có thể đã tải vào thời điểm người dùng cuộn đến đó.
Bạn có thể so sánh giữa ngưỡng khoảng cách từ khung nhìn cũ và 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) bên dưới:
Ngưỡng cũ so với ngưỡng mới:

và các ngưỡng mới so với LazySizes (một thư viện tải từng phần phổ biến của JS):

Chúng tôi cam kết hợp tác với cộng đồng tiêu chuẩn web để tìm hiểu về sự phù hợp tốt hơn về cách tiếp cận ngưỡng khoảng cách từ khung nhìn trên các trình duyệt khác nhau.
Hình ảnh phải bao gồm các thuộc tính về kích thước
Trong khi tải một hình ảnh, trình duyệt sẽ không biết ngay kích thước của hình ảnh đó, trừ phi chúng được chỉ định rõ ràng. Để cho phép trình duyệt đặt đủ không gian trên một trang cho hình ảnh, tất cả các thẻ <img>
nên bao gồm cả thuộc tính width
và height
. Nếu không chỉ định kích thước, thì hiện tượng thay đổi bố cục có thể xảy ra và dễ nhận thấy hơn trên các trang cần thời gian tải.
<img src="image.png" loading="lazy" alt="…" width="200" height="200">
Ngoài ra, hãy chỉ định trực tiếp giá trị của các giá trị này 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 để thiết lập kích thước là áp dụng cho thẻ <img>
, bất kể thẻ có được tải từng phần hay không. Với phương pháp tải từng phần, điều này có thể trở nên phù hợp hơn. Việc đặt width
và height
trên hình ảnh trong các trình duyệt hiện đại cũng cho phép các trình duyệt suy ra kích thước nội tại của chúng.
Trong hầu hết các trường hợp, hình ảnh vẫn tải từng phần nếu không bao gồm kích thước, nhưng bạn cần lưu ý một vài trường hợp hiếm gặp. Nếu không chỉ định width
và height
, kích thước hình ảnh ban đầu sẽ là 0×0 pixel. Nếu bạn có thư viện các hình ảnh như vậy, trình duyệt có thể kết luận rằng tất cả các hình ảnh đó ngay từ đầu sẽ nằm vừa trong khung nhìn, vì mỗi hình ảnh gần như không chiếm không gian và không có hình ảnh nào được đẩy ra ngoài màn hình. Trong trường hợp này, trình duyệt xác định rằng người dùng sẽ nhìn thấy tất cả các trang và quyết định tải mọi nội dung.
Ngoài ra, việc chỉ định kích thước hình ảnh giúp giảm nguy cơ thay đổi bố cục. Nếu bạn không thể bao gồm kích thước cho hình ảnh của mình, thì việc tải từng phần có thể là sự đánh đổi giữa việc tiết kiệm tài nguyên mạng và có nguy cơ cao hơn việc thay đổi bố cục.
Mặc dù tính năng tải từng phần trong Chromium được triển khai theo cách sao cho hình ảnh có thể được tải sau khi hiển thị, nhưng vẫn còn khả năng những hình ảnh này chưa được tải. Trong trường hợp này, việc thiếu các thuộc tính width
và height
trên những hình ảnh đó sẽ làm tăng ảnh hưởng của các thuộc tính này đến Điểm số tổng hợp về mức thay đổi bố cục.
Hình ảnh được xác định bằng phần tử <picture>
cũng có thể được tải từng phần:
<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 sẽ tải từ phần tử <source>
bất kỳ, nhưng thuộc tính loading
chỉ cần được thêm vào phần tử <img>
dự phòng.
Tránh tải từng phần hình ảnh ở khung nhìn hiển thị đầu tiên
Bạn nên tránh đặt loading=lazy
cho bất kỳ hình ảnh nào nằm trong khung nhìn hiển thị đầu tiên. Điều này đặc biệt phù hợp với hình ảnh LCP. Hãy xem bài viết Ảnh hưởng của hiệu suất khi tải từng phần quá nhiều để biết thêm thông tin.
Bạn chỉ nên thêm loading=lazy
vào những hình ảnh được đặt dưới màn hình đầu tiên, nếu có thể. Hình ảnh được tải nghiêm ngặt có thể được tìm nạp ngay lập tức, trong khi hình ảnh được tải từng phần thì trình duyệt hiện phải đợi cho đến khi biết được vị trí của hình ảnh trên trang mà dựa vào IntersectionObserver
.
Nói chung, mọi hình ảnh trong khung nhìn đều phải được tải nhanh chóng bằng cách sử dụng các chế độ mặc định của trình duyệt. Bạn không cần chỉ định loading=eager
cho trường hợp này đối với hình ảnh trong khung nhì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">
Hạ cấp nhẹ
Các trình duyệt không hỗ trợ thuộc tính loading
sẽ bỏ qua sự hiện diện của thuộc tính này. Mặc dù tất nhiên những trình duyệt này sẽ không được hưởng lợi từ việc tải từng phần, nhưng việc thêm thuộc tính này không ảnh hưởng tiêu cực đến trình duyệt.
Câu hỏi thường gặp
Google có dự định 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ị hoãn nếu Chế độ thu gọn được bật trên Chrome dành cho Android và thuộc tính loading
không được cung cấp hoặc không được đặt thành loading="auto"
. Tuy nhiên, chế độ Lite đã ngừng hoạt động (vì loading="auto"
không chuẩn) và hiện chưa có kế hoạch tự động tải từng phần của hình ảnh trong Chrome.
Tôi có thể thay đổi khoảng cách giữa một hình ảnh trước khi kích hoạt một lượt tải không?
Các giá trị này được mã hoá cứng và không thể thay đổi thông qua API. Tuy nhiên, các ngưỡng này có thể thay đổi trong tương lai khi trình duyệt thử nghiệm với các biến và khoảng cách ngưỡng khác nhau.
Hình nền CSS có thể tận dụng thuộc tính loading
không?
Không, hiện tại, bạn chỉ có thể sử dụng tính năng này với các thẻ <img>
.
Có nhược điểm nào đối với việc tải từng phần hình ảnh nằm trong khung nhìn của thiết bị không?
Sẽ an toàn hơn nếu bạn tránh đặt loading=lazy
vào hình ảnh trong màn hình đầu tiên vì Chrome sẽ không tải trước hình ảnh loading=lazy
trong trình quét tải trước và cũng sẽ trì hoãn việc tìm nạp những hình ảnh đó cho đến khi tất cả bố cục hoàn tất. Hãy xem phần Tránh tải từng phần hình ảnh ở khung nhìn hiển thị đầu tiên để biết thêm thông tin.
Thuộc tính loading
hoạt động như thế nào với hình ảnh nằm trong khung nhìn nhưng không hiển thị ngay (ví dụ: phía sau băng chuyền hoặc bị CSS ẩn đối với một số kích thước màn hình)?
Việc sử dụng loading="lazy"
có thể ngăn không cho các đường liên kết này được tải khi chúng không hiển thị, nhưng trong khoảng cách tính toán. Ví dụ: Chrome, Safari và Firefox không tải hình ảnh bằng cách sử dụng 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 khác để ẩn hình ảnh (chẳng hạn như sử dụng định kiểu opacity:0
) vẫn sẽ dẫn đến việc hình ảnh được tải. Hãy luôn kiểm tra kỹ lưỡng việc triển khai để đảm bảo việc triển khai hoạt động như dự kiến.
Nếu tôi đang sử dụng 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 gốc hiện có trong các trình duyệt hiện đại, bạn nên xem xét lại nếu vẫn cần 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 polyfill cho các trình duyệt không hỗ trợ thuộc tính này hoặc để có thêm quyền kiểm soát đối với thời điểm kích hoạt tải từng phần.
Làm cách nào để xử lý các trình duyệt không hỗ trợ tải từng phần?
Tạo đoạn mã polyfill hoặc 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 bạn. Bạn có thể sử dụng thuộc tính loading
để phát hiện xem tính năng có được hỗ trợ trong trình duyệt hay không:
if ('loading' in HTMLImageElement.prototype) {
// supported in browser
} else {
// fetch polyfill/third-party library
}
Ví dụ: lazysizes là một thư viện tải từng phần phổ biến của JavaScript. Bạn có thể phát hiện khả năng hỗ trợ thuộc tính loading
để tải từng phần dưới dạng thư viện dự phòng chỉ khi loading
không được hỗ trợ. Quy trình này diễn ra như sau:
- Thay thế
<img src>
bằng<img data-src>
để tránh tải sớm 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
chosrc
. - Nếu
loading
không được hỗ trợ, hãy tải một bản dự phòng (lazysize) và khởi tạo bản dự phòng đó. Theo các tài liệu về lazysizes, bạn sử dụng lớplazyload
như một cách để chỉ báo lazysize những hình ảnh cần tải từng phần.
<!-- 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>
Đây là bản minh hoạ của mẫu này. Hãy dùng thử trong một trình duyệt cũ hơn để xem tính năng dự phòng hoạt động.
Tính năng tải từng phần cho iframe có được hỗ trợ trong các trình duyệt không?
Hỗ trợ trình duyệt
- 77
- 79
- 16.4
<iframe loading=lazy>
cũng đã được chuẩn hoá và đã được triển khai trong Chromium và Safari. Tính năng này cho phép bạn tải từng phần iframe bằng thuộc tính loading
. Xem bài viết dành riêng này về tính năng tải từng phần của iframe để biết thêm thông tin.
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 được hiển thị cho người dùng dưới dạng tải từng phần của hình ảnh hoặc iframe giống như mọi hình ảnh hoặc iframe khác.
Hình ảnh được xử lý như thế nào khi một trang web được in?
Tất cả hình ảnh và iframe được tải ngay lập tức nếu trang được in. Xem vấn đề #875403 để biết thông tin 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 trở lên xét đến các phương pháp tải từng phần hình ảnh ngoài màn hình (có thể dùng nhiều ngưỡng khác nhau), cho phép vượt qua bài kiểm tra Trì hoãn hình ảnh ngoài màn hình.
Kết luận
Việc tích hợp chức năng hỗ trợ cho hình ảnh tải từng phần có thể giúp bạn cải thiện hiệu suất trang web dễ dàng hơn đáng kể.
Bạn có nhận thấy hành vi bất thường nào khi bật tính năng này trong Chrome không? Báo lỗi!