浏览器中的 Observer API 详解

258 阅读3分钟

浏览器中的 Observer API 详解

浏览器提供了多种 Observer(观察者)API,用于异步监听 DOM 变化、元素可见性、性能指标等场景。以下是主流 Observer 的分类与核心用法:


  1. MutationObserver 功能:监听 DOM 树的结构或属性变化。
    典型场景:
  • 防止水印被移除
  • 动态内容加载(如无限滚动列表)
  • 第三方插件侵入性修改监控
const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    if (mutation.type === 'childList') {
      console.log('子节点变化:', mutation.addedNodes);
    } else if (mutation.type === 'attributes') {
      console.log('属性变化:', mutation.attributeName);
    }
  });
});
 
// 配置监听选项 
observer.observe(document.body, {
  attributes: true,    // 监听属性变化 
  childList: true,     // 监听子节点增删 
  subtree: true        // 递归监听所有后代节点 
});
 
// 停止监听 
// observer.disconnect();
 
 
复制代码

  1. IntersectionObserver 功能:监听元素与视口(或指定容器)的交叉状态。
    典型场景:
  • 图片/组件懒加载
  • 广告曝光统计
  • 滚动动画触发
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('元素进入视口:', entry.target);
      entry.target.src = entry.target.dataset.src; // 懒加载图片 
      observer.unobserve(entry.target); // 仅触发一次 
    }
  });
}, {
  root: null,           // 默认视口 
  rootMargin: '0px',    // 视口边界扩展 
  threshold: 0.5        // 触发阈值(50%可见)
});
 
// 监听目标元素 
document.querySelectorAll('.lazy-img').forEach(img => {
  observer.observe(img);
});
 
 
复制代码

  1. ResizeObserver 功能:监听元素尺寸变化(包括 display: none 的元素)。
    典型场景:
  • 响应式布局调整
  • Canvas/图表自适应容器
  • 动态内容高度计算
const observer = new ResizeObserver((entries) => {
  entries.forEach(entry => {
    const { width, height } = entry.contentRect;
    console.log('元素尺寸变化:', width, height);
  });
});
 
// 监听指定元素 
observer.observe(document.getElementById('resizable-box'));
 
 
复制代码

  1. PerformanceObserver 功能:监听性能指标(如资源加载时长、长任务等)。
    典型场景:
  • 页面性能监控与优化
  • 关键资源加载耗时统计
  • 用户行为性能分析
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach(entry => {
    if (entry.entryType === 'resource') {
      console.log('资源加载耗时:', entry.name, entry.duration);
    }
  });
});
 
// 监听资源加载性能条目 
observer.observe({ entryTypes: ['resource', 'longtask'] });
 
 
复制代码

  1. ReportingObserver 功能:监听浏览器生成的报告(如废弃 API 警告、安全策略违规)。
    典型场景:
  • 废弃 API 使用监控
  • CSP(内容安全策略)违规日志收集
const observer = new ReportingObserver((reports) => {
  reports.forEach(report => {
    console.log('报告类型:', report.type);
    console.log('违规内容:', report.body);
  });
});
 
// 开始监听 
observer.observe();
 
 
复制代码

对比总结

API监听目标异步性典型场景浏览器支持
MutationObserverDOM 结构/属性变化动态内容、防篡改主流浏览器全支持
IntersectionObserver元素可见性懒加载、曝光统计主流浏览器全支持
ResizeObserver元素尺寸变化响应式布局、图表自适应主流浏览器全支持
PerformanceObserver性能指标性能监控、优化分析主流浏览器全支持
ReportingObserver浏览器报告废弃 API 监控、CSP 日志Chrome 70+、Firefox 支持

使用注意事项

  1. 内存管理:及时调用 disconnect() 或 unobserve() 避免内存泄漏。
  2. 性能优化:避免在回调中执行耗时操作,优先使用防抖/节流。
  3. 兼容性处理:旧版浏览器需引入 Polyfill(如 resize-observer-polyfill)。
  4. 阈值精细化:如 IntersectionObserver 的 threshold 可设为数组 [0, 0.25, 0.5, 1] 实现多级触发。

通过合理使用 Observer API,可显著提升复杂 Web 应用的性能和用户体验。