提高网站性能的Lazy Load图片完整指南
如果你想节省网站的带宽,并获得更快的网站加载速度,Lazy Load图像的JavaScript是一个好办法。
2019-2020年的大流行让我们都变得懒惰。由于没有选择,只能坐在家里,在那个阶段我们有35.82%的人发胖了,这都是由于我们的懒惰。幸运的是,那个阶段给了我们一个极好的机会来理解网络开发中一个有点类似的概念。那么,你如何定义 "懒惰 "这个词呢?虽然谷歌说,"不愿意工作",但我可以把它改写为 "在必要之前不愿意工作"。直到极有必要让一个懒惰的人搬到另一个地方,而不是那个糟糕的沙发,他们会坚持下去。
同样地,在CSS中,我们把那些不愿意从服务器到客户端(在我们的比喻中,从沙发到X地方)取用的图像称为懒惰的图像,直到极度必要时。懒惰图像将作为本博客的中心点。这个帖子将围绕着鼓励开发者使越来越多的图像与现实生活形成对比而进行懒惰。主要的景点,将抛出一些关于这些懒惰加载图像是什么,如何懒惰加载图像,以及开发人员可以将图像转换为懒惰的方法。
什么是懒惰加载图像?
在 "图像 "或计算机科学中,懒惰加载作为一个普遍的概念,避免了对该元素的获取请求,直到极其必要。例如,在Scala中,我们使用懒惰变量来避免它们的初始化和计算,直到必要时。这使得程序的执行速度更快,消耗的内存更少。
在CSS中,同样的概念被用来在必要时才加载图片。图像是一种以其大小而大量加载页面的东西。平均而言,谷歌分析认为,图像占到了网页的60%以上的字节。如果你拥有一个网站,你也可以检查你的页面速度洞察力,并了解图像对你的网页的负荷。
除了懒惰加载,还有很多方法,开发人员可以尝试优化网页性能。这些可能包括了解图像的响应性,使其尺寸更小,并使用正确的文件格式。但是,无论我们做什么,图像对网页的大部分内容都有贡献,今天没有适当的图像的网页是不完整的。因此,我们需要一些东西来帮助我们提高性能而不遗漏任何图像。
今天,图像为网页做出了如此大的贡献,因为它们很重要!
一项研究表明 65%的人通过视觉图像学习,而另一项由Brandwatch进行的研究则强调, 每天有32亿次图像分享被执行.
我们不能跳过网页上的图片,这就需要一种新的技术来加载图片,同时还能节省带宽。这就是懒惰加载图像的作用。懒惰加载图片背后的概念是,并非所有到达网页的用户都能完全阅读到最后。有些人在互联网上徘徊,发现这个页面与他们无关。有些人在他们不再需要的时候关闭了页面。
当我们知道大多数用户不会等待超过2秒的加载时,为每个用户完全加载页面是在浪费带宽和潜在用户。因此,为什么不跳过图片加载,而等待我们的用户到达放置图片的地方呢?这样一来,我们就可以肯定,如果我们对用户提出了一个沉重的要求,那也是值得的!对于那些在图片放置前放弃网页的人来说,网页变得更快,而服务器的请求变得更少。这是一个双赢的结果。
从下一节开始,我们将讨论 "如何懒惰地加载图片 "的三种方法--困难的,平庸的,以及简单的!
用JavaScript懒惰加载图片--困难的方法
第一种方法是传统的方法,这种方法已经使用了很长时间,可以使图像懒惰。实现懒惰加载图像--JavaScript 比本帖讨论的其他方法更复杂,但我相信它将沿途刷新你的JS技能,并将带来它自己的一系列好处。
为了在网页上加载图片,我们使用 "img "标签,其 "src "属性定义了图片的URL。
<img src = “URL” />
要对 "img "标签应用懒惰加载,我们需要首先删除 "src "标签。原因是,浏览器在看到 "src "标签时,会迅速加载所有的URL。因此,当我们在等待通过JavaScript触发事件时,我们的浏览器会在文档对象模型加载时就已经加载了图像。
为了防止图片的自动加载,我们使用了data-src属性而不是src。
<img data-src = “URL” />
在当前的演示中,我们将使用 "滚动 "事件来触发JavaScript函数,但由于这是你的网站,你可以采取任何你喜欢的事件来让浏览器知道加载图片的时间。
为了让浏览器知道我们想在一个事件后调用一个函数,我们需要添加事件监听器,如下:
document.addEventListener("roll", function\_name)
在这里,我们需要将function_name替换为实际的函数名称。比方说,我们的函数将被命名为 "Wake_Up_Image",以检查图像是否在视口中。如果是,就把它唤醒,也就是加载它:
document.addEventListener("roll", Wake\_Up\_Image)
现在我们需要实现我们的函数,如下所示:
function Wake_Up_Image() {
if(lazyloadTimeout) {
clearTimeout(lazyloadTimeout);
}
lazyloadTimeout = setTimeout(function() {
var scrollTop = window.pageYOffset;
lazyImages.forEach(function(img) {
if(img.offsetTop < (window.innerHeight + scrollTop)) {
img.src = img.dataset.src;
}
});
}
上述函数在图像上进行迭代,并计算图像相对于窗口的偏移量,以获得视口。如果发现图像在视口内,我们上面使用的data-src标签将通过img.src = img.dataset.src ,转换为src 标签。看到src标签,浏览器将在网页上加载图片。
超时函数是用来优化和提高性能的。这段代码在浏览器中可以正常工作,但需要轻微的性能改进。
首先,我们需要在lazyImages中捕获我们想要偷懒的图片。为此,我们可以在图像标签中实现 "lazy"作为一个类。
<img class = “lazy” data-src = “URL” /><pre>
Now we can capture these images using querySelector as follows:
<strong>var lazyImages = document.querySelectorAll("img.lazy");</strong>
As a next step, we should remove the eventListener as soon as the timeout becomes 0. This can be achieved through the removeEventListener:
<strong>document.removeEventListener("scroll", Wake_Up_Image);</strong>
Combining all of the above changes and optimizations, the overall code becomes:
<pre>
var lazyImages = document.querySelectorAll("img.lazy");
var lazyloadTimeout;
function Wake_Up_Image() {
if(lazyloadTimeout) {
clearTimeout(lazyloadTimeout);
}
lazyloadTimeout = setTimeout(function() {
var scrollTop = window.pageYOffset;
lazyImages.forEach(function(img) {
if(img.offsetTop < (window.innerHeight + scrollTop)) {
img.src = img.dataset.src;
img.classList.remove('lazy');
}
});
if(lazyloadImages.length == 0) {
document.removeEventListener("scroll", lazyload);
}
}, 15);
}
document.addEventListener("scroll", lazyload);
});
如果你觉得有必要,你可以添加其他的事件监听器--比如方向改变或窗口大小调整。
上述代码的输出结果如下:
好了!这就是我们要做的。有了这个实现,我们就完成了实现懒惰加载图像的硬方法。作为一个网页开发者,我可能不会在开发网页时使用懒惰加载图片的JavaScript来实现懒惰加载。如果最终的动机是只根据图片的视口可见度来加载图片,那么JavaScript就会比其他方法更长、更难。它比其他方法更容易出错,代码阅读也变得复杂。尽管如果你打算根据事件监听器来播放,没有什么比JavaScript能提供更好的控制。
在上面的演示中,你可能会感觉到图片的加载有一点延迟,在这段时间里,可以看到灰色的画布。作为一个开发者,你可以用一些主要的颜色给这个画布着色,以避免让用户注意到延迟。这只是一个轻微的UI调整,不会影响懒惰加载图像的性能。
使用交叉观察者API的懒惰加载图片--平庸的方式
观察到对基于视口的功能的高需求,JavaScript引入了一个新的API,叫做Intersection Observer。交叉观察者API观察目标元素与祖先元素或顶级文档视口之间的交集。交叉观察者API跳过了通常的JavaScript条件、循环和事件处理程序,这些在第一种方法中产生了复杂的代码。
我们将修改上面给出的代码,根据交叉观察者API进行调整,具体如下:
document.addEventListener("DOMContentLoaded", function() {
var lazyImages;
if ("IntersectionObserver" in window) {
lazyImages = document.querySelectorAll(".lazy");
var imageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var image = entry.target;
image.src = image.dataset.src;
image.classList.remove("lazy");
imageObserver.unobserve(image);
}
});
});
lazyImages.forEach(function(image) {
imageObserver.observe(image);
});
} else {
var lazyloadTimeout;
lazyImages = document.querySelectorAll(".lazy");
function lazyload () {
if(lazyloadTimeout) {
clearTimeout(lazyloadTimeout);
}
lazyloadTimeout = setTimeout(function() {
var scrollTop = window.pageYOffset;
lazyImages.forEach(function(img) {
if(img.offsetTop < (window.innerHeight + scrollTop)) {
img.src = img.dataset.src;
img.classList.remove('lazy');
}
});
if(lazyloadImages.length == 0) {
document.removeEventListener("scroll", lazyload);
}
}, 15);
}
document.addEventListener("scroll", lazyload);
}
})
unobserve "方法告诉交叉点观察者停止观察目标元素,而observed方法则相反。注意我们是如何在使用API时删除事件处理程序和偏移量计算的。
上面的代码产生了以下输出:
从上面的交互视频中可以看出,交叉观察者API的速度更快,在滚动事件上的表现也更好。在JavaScript中编写代码时产生的滞后现象在API中也不可见。
浏览器对交叉观察者API的支持
浏览器对相交观察者API的支持也很好,让我们可以自由地使用它,而不用担心崩溃的问题:

交叉观察者API是一个更好的选择,可以在网页上懒散地加载图片。浏览器中也有一种更直接的懒惰加载图片的方法,叫做 "加载 "属性。
使用 "加载 "属性懒散地加载图片--简单的方法
随着时间的推移,网页在不断增长。开发人员现在知道,图像对用户和他们对网站的看法有重大影响。因此,看到一个没有任何图片的网页已经成为一种罕见的现象。有些网页就是充满了图片,把它们的数量提高到十多张,有时甚至是15张。尽管这对每个人来说都是好事,但谷歌浏览器的开发者确实开始认真对待懒人加载问题。
由于我们的网页尺寸大幅增加,开发人员开始在他们的网站上使用懒人加载,以避免在一生中加载网页的尴尬。谷歌Chrome浏览器的开发者因此想到了在本地浏览器库中实现这一功能,这样开发者就可以跳过复杂的JS代码,直接实现懒人加载和src属性的存在。这个属性被称为 "加载 "属性。
loading "属性由三个值组成:
- auto(自动)。自动 "值取决于浏览器的内置功能。例如,谷歌浏览器会自动加载位于视口深处的图像以节省带宽。如果其他任何浏览器没有这种能力,图像将立即与页面一起加载。
- lazy: "lazy "值告诉浏览器,该图像需要在浏览器中缓慢地加载。
- eager(渴望)。eager "值用于告诉浏览器在加载内容时立即加载图像。eager "值与 "lazy "值正好相反。
由于我们需要懒散地加载图片,我们将在这里使用 "懒散"值。这是一个基于Chromium的更新,因此,将适用于所有基于Chromium的浏览器。
不需要实现JavaScript,对图像标签做一个小的补充就可以达到如下效果:
<img src = “URL” loading = “lazy”>
上述代码将带出与交叉点观察者API相同的输出,而无需任何额外的代码。那么,我们为什么不跳过一切,只使用本地的懒惰加载功能呢?
浏览器对加载属性的支持
浏览器对加载属性的支持情况如下:

Chrome浏览器和其他基于Chromium的浏览器显示完全支持。相比之下,Mozilla的Firefox目前对该属性提供部分支持。"加载 "属性更容易获得,但正如我上面提到的,如果你想玩弄事件,想对你的元素有更多的控制,JavaScript是最佳选择。
懒惰加载图像的JavaScript库
上述方法将邀请你在没有任何支持的情况下,对每个条件和循环进行复杂的编码。然而,与其他操作类似,JavaScript也来拯救我们,它有多个库,不仅可以鼓励图片的懒惰加载,也可以鼓励其他元素的懒惰加载。下面这些库将帮助你在JavaScript中懒散地加载元素:
除此以外,对于WordPress的粉丝,你可以使用A3 Lazy Load插件来非常有效地实现懒惰加载。
哪个选项是你最喜欢的?
懒加载图像是提高网站性能的一个很好的概念。如果你有一个网页,在网页的不同区域包含一些图片,懒加载将节省网络调用和加载网站的宝贵时间。不仅如此,懒惰加载还能提供实质性的性能提升,并降低你的整体成本。对于将所有图片托管到AWS云的人来说,尽量减少服务器调用可以降低你每月账单中的成本。
这并不意味着我们开始对网页上的所有内容进行懒加载。懒惰地加载所有东西可能听起来像一个巨大的性能奖励,但并不是必须的。今天的服务器没有那么慢,网络也更快。如果开发者开始分割本可以通过单个请求获取的部分,那么懒加载将增加服务器的调用。因此,建议使用懒惰加载,但不是在所有地方。
这篇文章中解释的方法正是为了在网页上懒散地加载图像。今天的三种方法有其重要性,也有其不足之处。JavaScript可能会让你很难受,但会为你提供更多的控制。加载属性是一个几秒钟的工作,但可能不会在所有的浏览器上呈现。有了这三种选择,我们很想知道你对这些方法的看法,作为一个开发和测试社区,你更喜欢哪一种。在评论区提到你的方法和使用它的理由,帮助社区从所有的开发者那里获得更多的个人见解。
测试愉快!