You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JS实现图片懒加载时浏览器重复加载图片的问题求助

解决图片懒加载中的重复加载问题

嘿,这个懒加载导致的图片重复加载问题我之前也碰到过,来给你拆解下原因和解决办法~

问题根源分析

  • 多次调用懒加载函数:你提到网站里Safari会重复加载10次,大概率是lazy()函数被触发了多次(比如滚动事件重复绑定、定时器重复执行)。每次调用都会遍历所有带[data-src]的元素,重新创建Image对象发起请求,哪怕图片已经加载过。
  • 缓存未被有效利用:理论上浏览器会缓存已加载的图片,但如果请求发起时缓存还没生效,或者代码没有判断图片是否已加载,就会重复发起请求。你的示例里用dot.png作为初始src,和目标图片的缓存完全无关,也会导致每次都要请求新的图片资源。

具体解决方案

1. 标记已处理的图片,避免重复操作

每次处理完一张图片后,给它加个标记(比如移除data-src或者添加自定义属性),这样下次调用lazy()时就跳过已经处理过的图片:

function lazy(){
  // 只处理未标记的图片
  $('[data-src]:not([data-processed])').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)
          .attr('data-processed', true) // 添加已处理标记
          .addClass('vis');
    });
  });
}

2. 维护已加载图片列表,提前复用缓存

可以用一个全局数组记录已经加载过的图片URL,处理前先检查是否已经加载过,直接复用缓存:

// 全局存储已加载的图片URL
var loadedImages = [];

function lazy(){
  $('[data-src]:not([data-processed])').each(function(){
    var $img = $(this);
    var src = $img.attr('data-src');
    
    // 如果已经加载过,直接赋值并标记
    if(loadedImages.includes(src)){
      $img.attr('src', src)
          .attr('data-processed', true)
          .addClass('vis');
      return;
    }
    
    var img = new Image();
    img.src = src;
    $(img).on('load', function(){
      console.log('loaded',src);
      loadedImages.push(src); // 加入已加载列表
      $img.attr('src', this.src)
          .attr('data-processed', true)
          .addClass('vis');
    });
  });
}

3. 避免lazy()函数被频繁调用

如果是通过滚动事件触发懒加载,一定要用**防抖(debounce)或者节流(throttle)**来限制调用频率,避免短时间内多次触发:

// 防抖函数:指定时间内只执行最后一次
function debounce(func, wait) {
  let timeout;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(context, args), wait);
  };
}

// 绑定滚动事件时用防抖包装
$(window).on('scroll', debounce(lazy, 200));

如果是定时器触发,也要确保不会重复设置定时器(比如用一个变量标记是否已经设置过)。

4. 针对Safari的缓存优化

Safari对缓存的处理相对严格,要确保你的图片服务器返回正确的缓存响应头(比如Cache-Control: public, max-age=31536000),这样浏览器才能正确识别并复用缓存的图片,减少重复请求。

为什么你的示例里Chrome也会重复加载?

你的示例里3秒后调用一次lazy(),但如果lazy()被多次调用(比如不小心重复绑定了触发逻辑),每次都会重新创建Image对象发起请求,而此时浏览器的缓存可能还没来得及生效,就会出现重复加载的情况。

内容的提问来源于stack exchange,提问作者nbl7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:32:19