如何使用JavaScript实现懒加载图片?

15
我对lazy loading的图片加载方式很感兴趣,即当滚动到图片位置时才会被加载。你有什么提示吗?

这回答解决了你的问题吗?如何使图像仅在视口中时加载? - Ciro Santilli OurBigBook.com
9个回答

18

这是一个使用插件的教程:http://www.webresourcesdepot.com/lazy-loading-of-images-resources-you-need/,这是jquery插件:http://www.appelsiini.net/projects/lazyload

基本上,您需要将虚拟图像放入src属性中,并添加另一个属性以存放实际的图像,JavaScript检测页面的滚动位置,一旦接近图像,就会加载图像数据。它通过将src替换为实际图像的源来实现。

这里有另一个解释:http://engineering.slideshare.net/2011/03/faster-page-loads-with-image-lazy-loading/


8

2020年以后的解决方案:

现在已经有一种本地的方法可以懒加载图片,在某些浏览器上已经能够正常工作。尽管标准化仍在进行中,但你现在就可以使用它!只需将loading属性添加到您的图像标签中,并将其设置为“lazy”:

<img
    src="picture.jpg"
    width="100"
    height="100"
    alt="descriptive text"
    loading="lazy"
>

就是这样。 兼容的浏览器将在当前视口足够接近时惰性地加载该图像。

更多信息请参见:

如果您需要旧版浏览器的解决方案,请查看MDN上的Lazy loading


这样使用延迟加载有什么缺点吗?如果没有,那么每个图像都应该使用loading属性吧? - Crashalot
1
https://stackoverflow.com/questions/61314750/risks-of-native-lazy-loading-with-the-html-loading-attribute - str
该解决方案目前不支持在Chrome中打印,请参见此错误报告。当您打印页面时,尚未加载的图像将在打印输出中丢失。 - Ingo Steinke

6
这里有一个示例,展示如何轻松实现此功能。
<img src="/images/lazy.jpg" data-real-src="/images/company-1.jpg">

"lazy.jpg"可以用于所有图片,这将导致只加载一个图像(它是一个1x1像素小重量的图像)。因此,考虑我有一个要访问250家商店的列表,每个商店都有一个公司标志。可能看起来像这样:

<img src="/images/lazy.jpg" data-real-src="/images/company-1.jpg">
<img src="/images/lazy.jpg" data-real-src="/images/company-2.jpg">
<img src="/images/lazy.jpg" data-real-src="/images/company-3.jpg">
...

接下来是魔法!在你的javascript文件中添加以下内容:
$('img[src="/images/lazy.jpg"]').each(function(index, el) {
    $(el).attr('src', $(el).data('real-src'));
});

并且,wacka-wacka,所有懒加载图片将被它们的“真实”图片替换。目的是让您的HTML页面加载更快(因为这些250家公司都在lazy.jpg中拥有相同的“标志”:)...但是JS在DOM完成加载后处理所有内容。

当然,这是一个jQuery解决方案。也可以使用纯JS实现。


3
浏览器级本地懒加载终于可用了。
<img src="image.png" loading="lazy" alt="…" width="200" height="200">

"<img loading=lazy>" 是由大多数基于Chromium的浏览器(Chrome、Edge、Opera)和Firefox支持的,对于WebKit(Safari)的实现正在进行中。Can I use 提供了有关跨浏览器支持的详细信息。不支持loading属性的浏览器会简单地忽略它,没有任何影响。 改进的数据节省以及与视窗距离阈值的改进"。

2
您可以使用 justlazy,它独立于像 jQuery 这样的依赖项,并且非常轻巧:
您只需要调用:

var placeholders = document.querySelectorAll(".load-if-visible");
for (var i = 0; i < placeholders.length; ++i) {
  Justlazy.registerLazyLoad(placeholders[i]);
}

占位符必须具有以下结构:

<span data-src="url/to/image" data-alt="some alt text"
      data-title="some title" class="load-if-visible">
</span>

出于SEO的原因,您可以使用任何其他占位符(例如占位符图像)。
此外,还有一个指南,介绍如何使用它以及有关图像懒加载的一些常规事项。

1
使用传统的将监听器附加到滚动事件上或利用setInterval来进行懒加载图片是非常低效的,因为每次调用getBoundingClientRect()都会强制浏览器重新布局整个页面,并且会给您的网站带来相当大的卡顿。请使用没有依赖关系的仅569字节的Lozad.js(使用InteractionObserver)来实现高效的懒加载图片。

1

2021-保持简单...

这里有很多插件推荐,根据您的使用情况,这些可能对您有价值。

如果您不想编写下面这个简短的代码片段,或者您需要已经构建好的回调函数,那么您可以使用我构建的插件,它基于这个确切的答案,且仅在最小化时为0.5kb。我的插件Simply Lazy,甚至可以与IE一起使用,只需添加polyfill即可。

归根结底,如果你只需要懒加载一些图片,那么就像这样简单:

<img data-src="your-image-path-here" class="lazyload" />

并且:

let observer = new IntersectionObserver((entries, observer) => {
  entries.forEach(function (entry) {
    if (entry.intersectionRatio > 0 || entry.isIntersecting) {
      const image = entry.target;
      observer.unobserve(image);

      if (image.hasAttribute('src')) {
        // Image has been loaded already
        return;
      }

      // Image has not been loaded so load it
      const sourceUrl = image.getAttribute('data-src');
      image.setAttribute('src', sourceUrl);

      image.onload = () => {
        // Do stuff
      }

      // Removing the observer
      observer.unobserve(image);
    }
  });
});

document.querySelectorAll('.lazyload').forEach((el) => {
  observer.observe(el);
});

使用Intersection Observer API可以使这一切变得非常简单。您还可以在shadowRoot中使用它,它也可以正常工作。
我还发现这篇文章有助于理解这里正在发生什么。

0

有很多方法可以实现延迟加载。过程就是只加载需要的内容。在软件场景中,您可以延迟加载任何内容。在网站上,大多数人在加载图像时使用它,因为大多数网站基本上只是图像。我的意思是网站的艺术品加上实际的人物图片,他们可能在您的服务器上有成千上万张图片。当您尝试同时加载所有这些图片时,通常会导致减速。在某个点上,它开始减慢进程。因此,延迟加载通常用于大型网站。就像我说的,您可以以多种方式做到这一点。已经给出了一种方法。将img标记预先加载,但src部分指向一个虚拟文件,大小较小。不要使用图形或图片...使用类似灰色块的东西...或者什么都不用。然后,当滚动部分接近滚动点且图像靠近时,它将运行一个函数,该函数将用真实的图像链接替换src。另一种方法是使用ajax和接近滚动点时将附加...使用实际的html代码加载带有图像的src。这就是我实际使用的方法。我编写了一个PHP文件来延迟加载图像、数据和文本。

这种方法的整个目的是在需要时从网站下载文件。当加载图像时,实际上是从您的服务器下载的。因此,当您开始处理较大的图像文件和过多的图像文件时,下载过程加上实际加载时间可能会增加。

0
这是一个演示示例项目:实时演示">实时演示 您可以尝试使用JavaScript实现图片延迟加载,通过使用小模糊占位图像,在完整图像下载完成之前显示。
<div class="blurred-img" style="background-image: url(imageName-small.jpg)">
  <img src="imageName-original.jpg" loading="lazy" />
</div>

要创建一个模糊的占位图像,可以使用自动化工具(如ffmpeg)生成原始图像的超低分辨率版本,只需在目标图像所在的目录中,在命令行上执行提供的代码即可。
ffmpeg -i imageName.jpg -vf scale=20:-1 imageName-small.jpg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接