加载可视化图像
重要程度: 4
假设我们有一个速度较慢的客户端,并且希望节省它们在移动端的流量。
为此,我们决定不立即显示图像,而是将其替换为占位符,如下所示:
<img src="placeholder.svg" width="128" height="128" data-src="real.jpg">
因此,最初所有图像均为 placeholder.svg
。当页面滚动到用户可以看到图像位置时 —— 我们就会将 src
更改为 data-src
的 src
,从而加载图像。
这是在 iframe
中的一个示例:
滚动它可以看到图像是“按需”加载的。
要求:
- 加载页面时,屏幕上的那些图像应该在滚动之前立即加载。
- 有些图像可能是常规图像,没有
data-src
。代码不应该改动它们。 - 一旦图像被加载,它就不应该在滚动进/出时被重新加载。
P.S. 如果你有能力,可以创建一个更高级的解决方案,以“预加载”当前位置下方/之后一页的图像。
P.P.S. 仅处理垂直滚动,不处理水平滚动。
onscroll
处理程序应该检查哪些图像是可见的,并显示它们。
我们还希望在页面加载时运行它,以检测即将可见的图像并加载它们。
该代码应该在文档加载完成时执行,以便可以访问文档内容。
或者将该代码放在 <body>
底部:
// ...页面内容在上面...
function isVisible(elem) {
let coords = elem.getBoundingClientRect();
let windowHeight = document.documentElement.clientHeight;
// 顶部元素边缘可见吗?
let topVisible = coords.top > 0 && coords.top < windowHeight;
// 底部元素边缘可见吗?
let bottomVisible = coords.bottom < windowHeight && coords.bottom > 0;
return topVisible || bottomVisible;
}
showVisible()
函数使用通过 isVisible()
实现的可见性检查,来加载可见图像:
function showVisible() {
for (let img of document.querySelectorAll('img')) {
let realSrc = img.dataset.src;
if (!realSrc) continue;
if (isVisible(img)) {
img.src = realSrc;
img.dataset.src = '';
}
}
}
showVisible();
window.onscroll = showVisible;
P.S. 此解决方案还有一个 isVisible
的变体,可以“预加载”当前文档滚动上方/下方 1 页内的图像