浏览器在使用 js 延迟加载时下载两倍的图像

browser downloading twice the images when lazy loading with js

我正在开发一个网站,我遇到了延迟加载图片的问题。

加载图像花费的时间太长,所以我检查了“浏览器网络”选项卡,发现 Safari 多次加载同一图像,从而减慢了其他媒体的加载速度。

我重现了代码以尽可能简单,当我延迟加载图像时,浏览器会加载它们两次。

<style type="text/css">
[data-src]{
  opacity: 0;
  transition: all .4s ease;
}
[data-src].vis{
  opacity: 1;
}
</style>

<img data-src="https://via.placeholder.com/150/045b1f/ffff11" src="dot.png">
<img data-src="https://via.placeholder.com/150/045b44/ffff22" src="dot.png">
<img data-src="https://via.placeholder.com/150/045b77/ffff33" src="dot.png">
<img data-src="https://via.placeholder.com/150/045b00/ffff44" src="dot.png">

<script type="text/javascript">

  function lazy(){
    $('[data-src]').each(function(){
      var $img = $(this);
      var src = $img.attr('data-src');
      var img = new Image();
      img.src = src;
      $(img).on('load', function(){
        console.log('loaded',src);
        $img.attr('src',this.src);
        $img.addClass('vis');
      });
    });  
  }

  jQuery(function($){

    setTimeout(function(){
      lazy();
    },3000)

  });
</script>

我也做了个CodePenhttps://codepen.io/nbl7/pen/GaoZXW

在我的网站上,这种情况只发生在 Safari 上,它甚至会加载同一张图片 10 次。可能是因为我调用延迟加载函数的时间不同。

在我提供的代码中它也发生在 Chrome。

浏览器是否应该知道已经加载了哪个图像并在不发出新请求的情况下缓存它们?

感谢您的帮助。

这是一个不会加载图像两次的代码:

function lazy() {
  $('[data-src]').each(function() {
    var img = this;
    var src = $(img).attr('data-src');
    $(img).attr('src', src);
    $(img).on('load', function() {
      console.log('loaded', src);
      $(img).addClass('vis');
    });
  });
}

jQuery(function($) {
  // lazy();
  setTimeout(function() {
    lazy();
  }, 3000)

});
[data-src] {
  opacity: 0;
  transition: all .4s ease;
}

[data-src].vis {
  opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<img data-src="https://via.placeholder.com/150/045b1f/ffff11" src="">
<img data-src="https://via.placeholder.com/150/045b44/ffff22" src="">
<img data-src="https://via.placeholder.com/150/045b77/ffff33" src="">
<img data-src="https://via.placeholder.com/150/045b00/ffff44" src="">

您在循环中设置了两次 img src,这意味着它加载了两次:

  • 这一行:img.src = src;(第 6 行)

  • 然后在这一行:$img.attr('src',this.src);(第 9 行)