用 IntersectionObserver 做图片懒加载和曝光埋点

Cold 发布于 2021-11-09 17 次阅读 278 字 预计阅读时间: 1 分钟 前端开发


以前做懒加载靠监听 scroll 事件 + getBoundingClientRect,频繁触发回流,性能差。IntersectionObserver 是浏览器原生提供的交叉观察器,性能好太多。

图片懒加载

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
}, {
  rootMargin: '100px 0px',
  threshold: 0
});

document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));

rootMargin 提前 100px 开始加载,用户体验更顺。加载完 unobserve,避免重复触发。

曝光埋点

曝光埋点要求「元素出现在视口内一定时间」才算曝光。可以配合 setTimeout。

const exposeObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const el = entry.target;
      el._timer = setTimeout(() => {
        reportExpose(el.dataset.id);
        exposeObserver.unobserve(el);
      }, 1000);
    } else {
      clearTimeout(entry.target._timer);
    }
  });
}, { threshold: 0.5 });

注意事项

  • threshold 0.5 表示元素一半可见才算,按业务调
  • 快速滚动时 isIntersecting 可能闪断,用定时器兜底
  • SPA 里组件销毁记得 unobserve,否则内存泄漏
  • 老浏览器(IE)不支持,需要 polyfill 或降级到 scroll 方案

这个 API 现在兼容性已经很好了,能用就用,比手写 scroll 监听省心。

和喜欢的一切在一起~
最后更新于 2021-11-09