Mặc dù hình ảnh và video tải từng phần có hiệu suất khả quan và có thể đo lường được những lợi ích thiết thực mà bạn không nên xem nhẹ. Nếu bạn trả lời sai, có thể là những hậu quả không mong muốn. Do đó, bạn cần phải duy trì những các mối lo ngại.
Chú ý đến nếp gấp
Bạn có thể muốn tải từng phần từng tài nguyên phương tiện trên trang bằng JavaScript, nhưng bạn cần phải chống lại sự cám dỗ này. Bất cứ thứ gì nằm ở trên Fold sẽ không được tải từng phần. Những tài nguyên đó nên được coi là quan trọng nội dung và do đó phải được tải bình thường.
Tính năng tải từng phần trì hoãn việc tải tài nguyên cho đến khi DOM tương tác
khi tập lệnh tải xong và bắt đầu thực thi. Đối với hình ảnh dưới
màn hình đầu tiên, điều này là tốt, nhưng các tài nguyên quan trọng trong màn hình đầu tiên nên được tải bằng
phần tử <img>
chuẩn để chúng xuất hiện sớm nhất có thể.
Tất nhiên, ngày nay, vị trí của màn hình đầu tiên không rõ ràng đến vậy khi các trang web được xem trên rất nhiều màn hình với kích thước khác nhau. Thiết bị nằm trong màn hình đầu tiên trên máy tính xách tay có thể nằm bên dưới nó trên thiết bị di động. Không có lời khuyên nào là không có dấu đầu dòng giải quyết điều này một cách tối ưu trong mọi tình huống. Bạn sẽ cần tiến hành một tài sản quan trọng trên trang của bạn và tải các hình ảnh đó theo cách thông thường thời trang.
Ngoài ra, bạn có thể không muốn quá nghiêm ngặt về đường gập
ngưỡng để kích hoạt tính năng tải từng phần. Điều này có thể lý tưởng hơn nếu bạn muốn
thiết lập vùng đệm một khoảng cách dưới màn hình đầu tiên để hình ảnh bắt đầu
tải trước khi người dùng cuộn vào khung nhìn. Ví dụ:
Intersection Observer API cho phép bạn chỉ định một thuộc tính rootMargin
trong một
khi bạn tạo một phiên bản IntersectionObserver
mới. Chiến dịch này
cung cấp hiệu quả cho các phần tử một vùng đệm, kích hoạt hành vi tải từng phần trước khi
phần tử nằm trong khung nhìn:
let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
// lazy-loading image code goes here
}, {
rootMargin: "0px 0px 256px 0px"
});
Nếu giá trị của rootMargin
trông giống với các giá trị mà bạn chỉ định cho một CSS
Đó là thuộc tính margin
! Trong trường hợp này,
lề dưới của phần tử được quan sát (khung nhìn của trình duyệt theo mặc định, nhưng
điều này có thể được thay đổi thành một phần tử cụ thể bằng cách sử dụng thuộc tính root
) được mở rộng thêm 256
điểm ảnh. Tức là hàm callback sẽ thực thi khi một phần tử hình ảnh được
trong phạm vi 256 pixel của khung nhìn và hình ảnh sẽ bắt đầu tải
trước khi người dùng thực sự nhìn thấy.
Để đạt được hiệu quả tương tự trong các trình duyệt không hỗ trợ Intersection Observe, hãy sử dụng mã xử lý sự kiện cuộn và điều chỉnh
Kiểm tra getBoundingClientRect
để thêm một vùng đệm.
Dịch chuyển bố cục và phần giữ chỗ
Nội dung nghe nhìn tải từng phần có thể gây ra hiện tượng dịch chuyển trong bố cục nếu không sử dụng phần giữ chỗ. Những thay đổi này có thể gây mất phương hướng cho người dùng và kích hoạt bố cục DOM tốn kém các hoạt động tiêu tốn tài nguyên hệ thống và góp phần gây ra hiện tượng giật. Ít nhất, hãy cân nhắc sử dụng phần giữ chỗ màu đồng nhất có cùng kích thước với hình ảnh mục tiêu hoặc các kỹ thuật như LQIP hoặc SQIP gợi ý nội dung của một nội dung nghe nhìn mục trước khi tải.
Đối với các thẻ <img>
, ban đầu src
phải trỏ đến một phần giữ chỗ cho đến khi đó
được cập nhật bằng URL hình ảnh cuối cùng. Sử dụng thuộc tính poster
trong
Phần tử <video>
để trỏ đến một hình ảnh giữ chỗ. Ngoài ra, hãy sử dụng width
và
Thuộc tính height
trên cả thẻ <img>
và <video>
. Điều này đảm bảo rằng
việc chuyển đổi từ phần giữ chỗ sang hình ảnh cuối cùng sẽ không làm thay đổi kích thước được hiển thị
của phần tử khi nội dung nghe nhìn tải.
Độ trễ khi giải mã hình ảnh
Việc tải các hình ảnh lớn trong JavaScript và thả chúng vào DOM có thể kết nối
luồng chính, khiến giao diện người dùng không phản hồi trong một khoảng thời gian ngắn
trong khi quá trình giải mã diễn ra. Giải mã hình ảnh không đồng bộ bằng decode
phương thức
trước khi chèn chúng vào DOM có thể làm giảm hiện tượng giật này, nhưng
hãy lưu ý: Tính năng này hiện chưa có ở mọi nơi và khiến logic tải từng phần trở nên phức tạp hơn.
Nếu muốn sử dụng mã này, bạn cần phải kiểm tra. Các chương trình dưới đây
cách bạn có thể sử dụng Image.decode()
với phương án dự phòng:
var newImage = new Image();
newImage.src = "my-awesome-image.jpg";
if ("decode" in newImage) {
// Fancy decoding logic
newImage.decode().then(function() {
imageContainer.appendChild(newImage);
});
} else {
// Regular image load
imageContainer.appendChild(newImage);
}
Truy cập đường liên kết CodePen này để xem tương tự như ví dụ thực tế này. Nếu hầu hết các hình ảnh của bạn khá nhỏ, điều này có thể không ảnh hưởng nhiều cho bạn nhưng chắc chắn có thể giúp giảm hiện tượng giật khi tải từng phần các hình ảnh lớn và chèn chúng vào DOM.
Khi nội dung không tải
Đôi khi, tài nguyên đa phương tiện không tải được vì lý do này hay lý do khác và xảy ra lỗi xảy ra. Khi nào việc này có thể xảy ra? Điều đó phụ thuộc, nhưng đây là một tình huống giả định dành cho bạn: Bạn có chính sách lưu vào bộ nhớ đệm HTML trong một khoảng thời gian ngắn (ví dụ: năm phút) và người dùng truy cập vào trang web hoặc mở một thẻ cũ trong trong một khoảng thời gian dài (ví dụ: một vài giờ) và quay lại để đọc nội dung. Tại một thời điểm nào đó trong quá trình này, sẽ xảy ra việc triển khai lại. Trong quá trình triển khai này, một tên của tài nguyên hình ảnh thay đổi do tạo phiên bản dựa trên hàm băm hoặc đã bị xoá hoàn toàn. Vào thời điểm người dùng tải từng phần hình ảnh, tài nguyên sẽ không khả dụng và do đó không thành công.
Mặc dù trường hợp này tương đối hiếm nhưng bạn nên có một bản sao lưu nếu không thể tải từng phần. Đối với hình ảnh, giải pháp này có thể trông giống như sau:
var newImage = new Image();
newImage.src = "my-awesome-image.jpg";
newImage.onerror = function(){
// Decide what to do on error
};
newImage.onload = function(){
// Load the image
};
Những việc bạn quyết định làm trong trường hợp xảy ra lỗi phụ thuộc vào ứng dụng của bạn. Cho Ví dụ: bạn có thể thay thế khu vực giữ chỗ hình ảnh bằng một nút cho phép người dùng cố tải lại hình ảnh hoặc chỉ hiển thị thông báo lỗi trong phần giữ chỗ hình ảnh.
Cũng có thể phát sinh các tình huống khác. Dù bạn làm gì, tốt nhất là tín hiệu cho người dùng khi xảy ra lỗi và có thể đưa ra biện pháp xử lý để thực hiện nếu có vấn đề xảy ra.
Tính khả dụng của JavaScript
Bạn không nên cho rằng JavaScript luôn có sẵn. Nếu bạn định
tải từng phần hình ảnh, hãy cân nhắc cung cấp mã đánh dấu <noscript>
để hiển thị hình ảnh bằng
không có JavaScript theo chữ hoa/chữ thường. Ví dụ dự phòng đơn giản nhất có thể bao gồm
sử dụng các phần tử <noscript>
để phân phát hình ảnh nếu JavaScript tắt:
Nếu JavaScript bị tắt, người dùng sẽ thấy cả hình ảnh phần giữ chỗ và
hình ảnh chứa các phần tử <noscript>
. Để đi xung quanh, hãy đặt
một lớp no-js
trên thẻ <html>
như sau:
<html class="no-js">
Sau đó, hãy đặt một dòng tập lệnh cùng dòng trong <head>
trước bất kỳ biểu định kiểu nào
được yêu cầu qua các thẻ <link>
sẽ xoá lớp no-js
khỏi <html>
nếu JavaScript bật:
<script>document.documentElement.classList.remove("no-js");</script>
Cuối cùng, hãy sử dụng một số CSS để ẩn các phần tử có lớp lazy khi JavaScript không có sẵn:
.no-js .lazy {
display: none;
}
Điều này không ngăn hình ảnh giữ chỗ tải, nhưng kết quả sẽ cao hơn đáng mong muốn. Những người đã tắt JavaScript nhận được lợi ích khác ngoài phần giữ chỗ tốt hơn là phần giữ chỗ và không có nội dung hình ảnh có ý nghĩa tất cả.