Ngày xuất bản: 16 tháng 8 năm 2019
Tương tự như phần tử hình ảnh, bạn cũng có thể tải video theo phương thức tải lười. Video thường được tải bằng phần tử <video>
, mặc dù đối với video được lưu trữ trên các dịch vụ khác như YouTube, chúng có thể sử dụng <iframe>
(trong trường hợp đó, hãy xem bài viết về iframe tải lười).
Cách tải lười <video>
phụ thuộc vào trường hợp sử dụng, vì có một số giải pháp khác nhau.
Đối với video không tự động phát
Tốt nhất là bạn nên tránh tự động phát video vì tính năng này sẽ khiến người dùng mất quyền kiểm soát. Trong những trường hợp này, cách tốt nhất để tránh tải toàn bộ video là chỉ định thuộc tính preload
trên phần tử <video>
:
<video controls preload="none" poster="one-does-not-simply-placeholder.jpg">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
Ví dụ trước sử dụng thuộc tính preload
có giá trị là none
để ngăn trình duyệt tải trước bất kỳ dữ liệu video nào. Thuộc tính poster
cung cấp cho phần tử <video>
một phần giữ chỗ sẽ chiếm không gian trong khi video tải.
Trong hầu hết các trình duyệt, preload
mặc định là metadata
và một phần của video được tải trước bằng tiêu đề Content-Range
. Điều này có thể dẫn đến việc tải nhiều dữ liệu hơn mong muốn, đặc biệt là nếu trình duyệt không hỗ trợ tiêu đề Content-Range
. Ngay cả khi được hỗ trợ, trình duyệt cũng không thể biết siêu dữ liệu được lưu trữ ở byte nào và siêu dữ liệu có thể không được lưu trữ ở đầu tệp. Do đó, cách tốt nhất để tránh tải video là chỉ định none
và sử dụng preload="none"
.
Bạn có thể cải tiến tính năng này để tải trước siêu dữ liệu khi người dùng di chuột qua video bằng thuộc tính onmouseenter
(hoặc bằng trình xử lý sự kiện mouseenter
tương đương):
<video controls
preload="none"
poster="one-does-not-simply-placeholder.jpg"
onmouseenter="event.target.setAttribute('preload','metadata')">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
Điều này không chỉ làm giảm độ trễ khi người dùng phát video mà còn hiển thị thời lượng của video ngay khi họ phát.
Video có thể đủ điều kiện trở thành video đề xuất trong LCP. Hình ảnh poster
sẽ tải nhanh hơn video. Vì vậy, nếu hình ảnh này là một đề xuất LCP, bạn nên sử dụng hình ảnh áp phích, đồng thời tải trước hình ảnh đó bằng giá trị thuộc tính fetchpriority
là "high"
:
<link rel="preload" href="one-does-not-simply-placeholder.jpg" as="image" fetchpriority="high">
<video controls preload="none"
poster="one-does-not-simply-placeholder.jpg"
onmouseenter="event.target.setAttribute('preload','metadata')">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
Đối với video đóng vai trò thay thế ảnh GIF động
Video tự động phát thường được dùng cho ảnh động nhanh kiểu GIF. Mặc dù được sử dụng rộng rãi, nhưng ảnh GIF động vẫn thua kém video tương đương về một số khía cạnh, đặc biệt là về kích thước tệp. Ảnh GIF động có thể có kích thước dữ liệu lên đến vài megabyte. Các video có chất lượng hình ảnh tương tự thường có kích thước nhỏ hơn nhiều.
Việc sử dụng phần tử <video>
để thay thế cho ảnh GIF động không đơn giản như phần tử <img>
. Ảnh GIF động có 3 đặc điểm:
- Các video này sẽ tự động phát khi tải.
- Các vòng lặp này lặp lại liên tục (mặc dù không phải lúc nào cũng như vậy).
- Video không có bản âm thanh.
Bạn có thể thực hiện việc này bằng phần tử <video>
như sau:
<video autoplay muted loop playsinline>
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
Các thuộc tính autoplay
, muted
và loop
đã tự giải thích. playsinline
là cần thiết để tính năng tự động phát xảy ra trong iOS. Giờ đây, bạn đã có một video thay thế dạng GIF có thể sử dụng được trên nhiều nền tảng. Nhưng làm cách nào để tải từng phần? Để bắt đầu, hãy sửa đổi mã đánh dấu <video>
cho phù hợp:
<video class="lazy" autoplay muted loop playsinline width="610" height="254" poster="one-does-not-simply.jpg">
<source data-src="one-does-not-simply.webm" type="video/webm">
<source data-src="one-does-not-simply.mp4" type="video/mp4">
</video>
Bạn sẽ thấy thuộc tính poster
được thêm vào. Thuộc tính này cho phép bạn chỉ định một phần giữ chỗ để chiếm không gian của phần tử <video>
cho đến khi video được tải lười. Cũng như các ví dụ về tính năng tải lười <img>
, hãy lưu trữ URL video trong thuộc tính data-src
trên mỗi phần tử <source>
. Từ đó, hãy sử dụng mã JavaScript tương tự như các ví dụ về tính năng tải lười hình ảnh dựa trên Intersection Observer:
document.addEventListener("DOMContentLoaded", function() {
var lazyVideos = [].slice.call(document.querySelectorAll("video.lazy"));
if ("IntersectionObserver" in window) {
var lazyVideoObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(video) {
if (video.isIntersecting) {
for (var source in video.target.children) {
var videoSource = video.target.children[source];
if (typeof videoSource.tagName === "string" && videoSource.tagName === "SOURCE") {
videoSource.src = videoSource.dataset.src;
}
}
video.target.load();
video.target.classList.remove("lazy");
lazyVideoObserver.unobserve(video.target);
}
});
});
lazyVideos.forEach(function(lazyVideo) {
lazyVideoObserver.observe(lazyVideo);
});
}
});
Khi tải lười một phần tử <video>
, bạn cần lặp lại tất cả các phần tử <source>
con và chuyển đổi thuộc tính data-src
của các phần tử đó thành thuộc tính src
. Sau khi thực hiện việc đó, bạn cần kích hoạt quá trình tải video bằng cách gọi phương thức load
của phần tử. Sau đó, nội dung nghe nhìn sẽ bắt đầu phát tự động theo thuộc tính autoplay
.
Khi sử dụng phương thức này, bạn sẽ có một giải pháp video mô phỏng hành vi của ảnh GIF động, nhưng không gây ra mức sử dụng dữ liệu chuyên sâu như ảnh GIF động và bạn có thể tải lười nội dung đó.
Thư viện tải từng phần
Các thư viện sau đây có thể giúp bạn tải video theo kiểu tải lười:
- vanilla-lazyload và lozad.js là các tuỳ chọn siêu nhẹ chỉ sử dụng Intersection Observer. Do đó, các tính năng này có hiệu suất cao, nhưng cần được bổ sung trước khi bạn có thể sử dụng trên các trình duyệt cũ.
- yall.js là một thư viện sử dụng Intersection Observer và quay lại trình xử lý sự kiện. Trình phát cũng có thể tải hình ảnh
poster
của video theo kiểu tải lười bằng thuộc tínhdata-poster
. - Nếu cần một thư viện tải lười dành riêng cho React, bạn có thể cân nhắc sử dụngreact-lazyload. Mặc dù không sử dụng Intersection Observer, nhưng thư viện này vẫn cung cấp một phương thức tải hình ảnh từng phần quen thuộc cho những người đã quen phát triển ứng dụng bằng React.
Mỗi thư viện tải lười này đều được ghi chép cẩn thận, với nhiều mẫu đánh dấu cho nhiều nỗ lực tải lười của bạn.