1. ResizeObserver核心作用监听元素的尺寸变化如宽度、高度改变无需通过window.resize监听整个窗口性能更优。典型场景响应式组件适配、图表容器尺寸更新、自定义滚动条宽度调整等。2. PerformanceObserver核心作用监听浏览器的性能指标数据如页面加载时间、资源加载状态、长任务等用于性能监控和分析。典型场景统计首屏加载时间、检测长任务避免页面卡顿、监控资源JS/CSS/ 图片加载耗时等。3. IntersectionObserver核心作用监听目标元素与视口 / 祖先元素的交叉状态是否可见、可见比例替代传统的滚动监听 位置计算减少重绘重排。典型场景图片懒加载、滚动触发动画、无限滚动列表、广告曝光统计等。4. MutationObserver核心作用监听DOM 节点的变化如节点新增 / 删除、属性修改、文本内容变化实时响应 DOM 更新。典型场景监听表单值变化、监控第三方组件 DOM 渲染、实现 DOM 变化的日志记录等。综上前端中常用的、功能明确的 Observer API 共4 个核心差异在于监听的 “目标对象” 不同分别对应尺寸变化、性能数据、交叉可见性、DOM 变化。1.ResizeObserver是浏览器原生 API专门监听 DOM 元素尺寸变化宽 / 高改变、旋转、窗口缩放等比传统的window.onresize更精准、性能更好。下面给你可直接运行的完整 HTML 代码包含基础用法、监听多个元素、销毁监听。完整示例代码!DOCTYPE html html langzh-CN head meta charsetUTF-8 titleResizeObserver 使用示例/title style * { box-sizing: border-box; margin: 20px; } /* 可拖拽的盒子方便测试尺寸变化 */ .resize-box { width: 300px; height: 200px; border: 2px solid #2196F3; padding: 10px; resize: both; /* 允许拖拽缩放 */ overflow: auto; } .box2 { border-color: #f44336; margin-top: 30px; } #log { background: #f5f5f5; padding: 10px; min-height: 100px; white-space: pre-wrap; } /style /head body h3拖拽右下角缩放盒子 ↘/h3 !-- 要监听的元素 1 -- div classresize-box idbox1盒子1可拖拽缩放/div !-- 要监听的元素 2 -- div classresize-box box2 idbox2盒子2可拖拽缩放/div div尺寸变化日志/div div idlog/div button onclickstopObserver()停止监听所有元素/button script // 1. 获取 DOM 元素 const box1 document.getElementById(box1); const box2 document.getElementById(box2); const log document.getElementById(log); // 2. 创建 ResizeObserver 实例 const resizeObserver new ResizeObserver(entries { // entries所有触发尺寸变化的元素数组 entries.forEach(entry { // 变化的元素 const targetEl entry.target; // 最新尺寸 const { width, height } entry.contentRect; // 打印日志 const logText 【${targetEl.id}】尺寸变化 → 宽${width.toFixed(0)}px高${height.toFixed(0)}px ; log.innerHTML logText log.innerHTML; // 你可以在这里执行业务逻辑 // 比如重新渲染图表、调整布局、更新样式等 }); }); // 3. 开始监听元素 resizeObserver.observe(box1); resizeObserver.observe(box2); // 4. 停止监听重要页面销毁/不需要时调用 function stopObserver() { // 停止监听单个元素 // resizeObserver.unobserve(box1); // 停止监听所有元素 resizeObserver.disconnect(); log.innerHTML ✅ 已停止所有尺寸监听\n log.innerHTML; } /script /body /html核心 API 说明1. 创建观察者const observer new ResizeObserver(entries { // 尺寸变化时触发 });2. 监听元素observer.observe(dom元素);3. 停止监听必用// 停止单个元素 observer.unobserve(dom元素); // 停止所有页面卸载/组件销毁时用 observer.disconnect();4. 关键参数entry.contentRect尺寸变化后你能拿到的核心数据width/height元素内容区域宽高最常用top/left/right/bottom相对位置适用场景图表自适应容器大小弹窗 / 侧边栏尺寸变化时重新布局响应式自定义组件代替低效的window.onresize浏览器兼容性支持Chrome、Firefox、Safari 13.1、Edge所有现代浏览器都能用无需引入任何库。3. IntersectionObserver看下tuniu的页面这有两个属性src和data-src一、第一次尝试!DOCTYPE html html langen head meta charsetUTF-8 / meta nameviewport contentwidthdevice-width, initial-scale1.0 / titleLazy Load Images/title style /* Placeholder style */ .placeholder { width: 300px; height: 200px; background-color: #ccc; display: flex; justify-content: center; align-items: center; } /style /head body !-- Placeholder for the image -- div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div div classplaceholderLoading.../div !-- Actual image element with />二、IntersectionObserver!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleIntersectionObserver 示例 - 图片懒加载/title style .image-container { width: 300px; height: 200px; margin: 20px; border: 1px solid #ccc; display: flex; justify-content: center; align-items: center; } .image-container img { max-width: 100%; max-height: 100%; display: block; } .longBlock{ height:1000px; width:1px; border:1px solid red; margin:10px; } /style /head body div classimage-container img data-srchttps://img1.tuniucdn.com/site/images/yj_2016/init-img.jpg altLazy-loaded Image /div div classlongBlock/div div classimage-container img data-srchttps://img1.tuniucdn.com/site/images/yj_2016/init-img.jpg altLazy-loaded Image /div div classlongBlock/div div classimage-container img data-srchttps://img1.tuniucdn.com/site/images/yj_2016/init-img.jpg altLazy-loaded Image /div script // 获取所有带有 data-src 属性的图片元素 const lazyImages document.querySelectorAll(img[data-src]); // 创建 IntersectionObserver 实例 const observer new IntersectionObserver((entries, observer) { entries.forEach(entry { // 当目标元素进入视窗时 if (entry.isIntersecting) { const lazyImage entry.target; lazyImage.src lazyImage.dataset.src; // 加载图片 observer.unobserve(lazyImage); // 停止观察该图片元素 } }); }); // 遍历所有图片元素开始观察 lazyImages.forEach(image { observer.observe(image); }); /script /body /htmlIntersectionObserver 是一个用于监视元素与其祖先元素或顶级文档视窗交叉状态的 API。这个 API 特别适用于实现无限滚动、延迟加载图片、懒加载和实现类似的场景。它的工作原理是观察一个或多个目标元素与其祖先元素或顶级文档视窗viewport的交叉状态。当目标元素进入或离开视窗或其祖先元素时IntersectionObserver 会触发回调函数从而允许开发者执行相应的操作。IntersectionObserver 提供了一种高效的方法来监视元素的可见性而无需频繁地检查它们的位置或大小这对于性能优化非常有用。它可以减少因为频繁的滚动事件监听而引起的性能问题并且更容易实现各种基于元素可见性的功能。例如你可以使用 IntersectionObserver 来实现以下功能无限滚动加载当页面滚动到页面底部时动态加载更多内容。图片懒加载只有当图片进入视窗时才加载图片资源以节省带宽和加快页面加载速度。广告展示只有当广告元素进入用户视野时才加载广告内容提高广告效果。动画触发当某个元素进入或离开视窗时触发动画效果。网页性能优化根据元素的可见性动态加载或卸载资源以提高页面加载速度和性能。总之IntersectionObserver 是一个非常有用的 Web API它可以帮助开发者实现各种与元素可见性相关的功能并且能够提高网页的性能和用户体验。三、react中//LazyImage.jsx import React, { useState, useRef, useEffect } from react; const LazyImage ({ src, alt }) { const [isVisible, setIsVisible] useState(false); const imageRef useRef(null); useEffect(() { const observer new IntersectionObserver((entries) { entries.forEach((entry) { // 当目标元素进入视窗时 if (entry.isIntersecting) { setIsVisible(true); // 设置图片可见 observer.unobserve(entry.target); // 停止观察 } }); }); if (imageRef.current) { observer.observe(imageRef.current); // 开始观察图片元素 } return () { if (imageRef.current) { observer.unobserve(imageRef.current); // 组件卸载时停止观察 } }; }, [src]); // 仅在 src 发生变化时重新运行 useEffect return ( img ref{imageRef} src{isVisible ? src : } alt{alt} / ); }; export default LazyImage; //App.jsx import React from react; import LazyImage from ./LazyImage; const App () { return ( div style{{height:1000px,width:10px,border:1px solid red}}/div LazyImage srchttps://img1.tuniucdn.com/site/images/yj_2016/init-img.jpg altLazy-loaded Image / div style{{height:1000px,width:10px,border:1px solid red}}/div LazyImage srchttps://img1.tuniucdn.com/site/images/yj_2016/init-img.jpg altLazy-loaded Image / div style{{height:1000px,width:10px,border:1px solid red}}/div LazyImage srchttps://img1.tuniucdn.com/site/images/yj_2016/init-img.jpg altLazy-loaded Image / div style{{height:1000px,width:10px,border:1px solid red}}/div LazyImage srchttps://img1.tuniucdn.com/site/images/yj_2016/init-img.jpg altLazy-loaded Image / div style{{height:1000px,width:10px,border:1px solid red}}/div LazyImage srchttps://img1.tuniucdn.com/site/images/yj_2016/init-img.jpg altLazy-loaded Image / / ); }; export default App;4.MutationObserver 水印!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleDocument/title /head body div idcontainer div idwatermark 水印 /div div1212121/div /div script const container document.getElementById(container); const ob new MutationObserver((mutations) { console.log(mutations); mutations.forEach((mutation) { if (mutation mutation.removedNodes.length 0) { mutation.removedNodes.forEach((e) { if (e.id watermark) { container.appendChild(e); } }); } if (mutation.type attributes) { const parent mutation.target.parentElement; parent.removeChild(mutation.target); // mutation.target.style.display block; // console.log(mutation.target.style., -----); } console.log(mutation); }); }); ob.observe(container, { childList: true, //新增和删除 subtree: true, //所有的子节点 attributes: true, //所有子节点属性变化 // characterData: true, // attributeOldValue: true, // characterDataOldValue: true, // attributeFilter: [src, href], // attributeOldValue: true, // characterDataOldValue: true, }); /script /body /html