Set用于懒加载图片URL去重与高效查存,时间复杂度O(1),避免重复请求;初始化时遍历data-src存入,IntersectionObserver回调中用has()校验并delete()移除,确保每张图只加载一次。

在长页面中用 Set 记录待延迟加载的图片 URL,核心是“去重 + 高效查存”,避免重复绑定或重复请求。它不直接参与滚动监听逻辑,而是作为 URL 的唯一容器,配合 IntersectionObserver 或 scroll 事件使用。
为什么用 Set 而不是数组或对象?
Set 天然保证 URL 唯一性,插入、检查时间复杂度都是 O(1),比数组 includes()(O(n))快得多,也比用对象键模拟更语义清晰、无类型转换风险(比如 {'1': true} 和 {1: true} 实际等价)。
如何用 Set 收集待加载图片 URL
通常在页面初始化时遍历所有带 data-src 的 <img>,把 URL 存入 Set;后续滚动中只处理尚未加载过的 URL:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 用
const pendingUrls = new Set()初始化 - 遍历所有懒加载图片:
img.dataset.src && pendingUrls.add(img.dataset.src) - 当某张图进入视口,加载后立即从 Set 中删除:
pendingUrls.delete(url) - 可选:用
pendingUrls.size监控剩余待加载数量
和 IntersectionObserver 配合的典型写法
避免手动节流,推荐用 IntersectionObserver,并在回调中结合 Set 判断是否已处理过:
立即学习“Java免费学习笔记(深入)”;
const pendingUrls = new Set();
const imgs = document.querySelectorAll('img[data-src]');
imgs.forEach(img => {
if (img.dataset.src) pendingUrls.add(img.dataset.src);
});
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
const url = img.dataset.src;
if (url && pendingUrls.has(url)) {
img.src = url;
img.removeAttribute('data-src');
pendingUrls.delete(url); // 确保只加载一次
}
}
});
}, { threshold: 0.1 });
imgs.forEach(img => observer.observe(img));
注意边界情况
某些场景下需额外判断,防止误删或漏存:
- 图片可能被 JS 动态插入,需在插入后调用
pendingUrls.add(newUrl) - 用户快速滚动可能触发多次回调,
pendingUrls.has(url)是关键守门员 - 如果支持图片加载失败重试,不要在失败时
delete,而应换用 Map 记录状态(如{ url: 'pending' | 'loaded' | 'error' }) - 不需要持久化,页面刷新后 Set 自动清空,符合预期

















