当前位置: 首页 > 科技观察

五种浏览器观察器你用过几个?

时间:2023-03-13 11:24:25 科技观察

在Web开发中,我们经常要处理用户交互。我们会使用addEventListener来添加事件监听器来监听用户的各种操作,比如click、mousedown、mousemove、input等,这些都是用户直接触发的事件。那么一些不是由用户直接触发的事件呢?比如元素永远不可见,元素大小发生变化,元素的属性和子节点的修改等,这些事件如何监控?浏览器提供了5个Observer来监听这些变化:MutationObserver、IntersectionObserver、PerformanceObserver、ResizeObserver、ReportingObserver。我们分别来看一下:IntersectionObserver一个元素从不可见到可见,从可见到不可见,如何监听这个变化?使用IntersectionObserver。IntersectionObserver可以监控一个元素的交集与可见区域的比例,然后当可见比例达到一定阈值时触发回调。我们准备两个元素:BOX111

BOX222
加上样式:#box1,#box2{width:100px;高度:100px;背景:蓝色;颜色:#fff;position:relative;}#box1{top:500px;}#box2{top:800px;}这两个元素分别在500和800px的高度,我们监测它们的可见性变化。constintersectionObserver=newIntersectionObserver(function(entries){console.log('info:');entries.forEach(item=>{console.log(item.target,item.intersectionRatio)})},{阈值:[0.5,1]});intersectionObserver.observe(document.querySelector('#box1'));intersectionObserver.observe(document.querySelector('#box2'));创建一个IntersectionObserver对象,监听box1和box2两个元素,当可见比例达到0.5和1时触发回调。运行浏览器:可以看到元素box1和box2在可见范围达到一半(0.5)时触发回调和完整的(1)分别。这有什么用?这非常有用。我们在做一些数据采集的时候,想知道某个元素是否可见,什么时候可见。我们可以通过这个api来监控和做图片的懒加载,当视觉比例达到一定比例时就可以触发加载。除了监控元素的可见性,还可以监控元素属性和子节点的变化:MutationObserver监控一个普通的JS对象的变化,我们会使用Object.defineProperty或者Proxy:,监控元素属性和子节点的变化节点,我们可以使用MutationObserver:MutationObserver可以监听元素属性的修改,及其子节点的增删改查。我们准备了这样一个盒子:
加上样式:#box{width:100px;高度:100px;背景:蓝色;position:relative;}就是这样:我们定期修改它:setTimeout(()=>{box.style.background='red';},2000);setTimeout(()=>{constdom=document.createElement('button');dom.textContent='dongdongdong';box.appendChild(dom);},3000);setTimeout(()=>{document.querySelectorAll('button')[0].remove();},5000);在2秒时,将背景颜色更改为红色,在3秒时,添加按钮子元素,在5秒时,删除第一个按钮。然后监控它的变化:constmutationObserver=newMutationObserver((mutationsList)=>{console.log(mutationsList)});mutationObserver.observe(box,{attributes:true,childList:true});创建一个MutationObserver对象并监听盒子的属性和子节点的变化。运行浏览器:可以看到它在三次变化的过程中监听并打印了一些信息:第一次变化是attributes,属性是style:第二次变化是childList,增加了一个节点:第三次也是一个改变的childList,一个节点被删除:它都被监控了!这有什么用?比如一篇文章的水印是通过devtools去掉的,那么你可以通过MutationObserver监测这个变化,然后重新添加,让水印去掉。失去。当然还有很多其他的用途,这里只是介绍一下功能。除了监听元素的可见性、属性和子节点的变化,还可以监听尺寸的变化:我们可以使用addEventListener监听ResizeObserver窗口中的resize事件。元素呢?元素可以使用ResizeObserver来监控尺寸变化。当修改宽高时,会触发回调。我们准备这样一个元素:
添加样式:#box{width:100px;高度:100px;background:blue;}修改它的高度为2s:constbox=document.querySelector('#box');setTimeout(()=>{box.style.width='200px';},3000);然后我们使用ResizeObserver来监听它的变化:constresizeObserver=newResizeObserver(entries=>{console.log('currentsize',entries)});resizeObserver.observe(box);在浏览器中运行:监听大小变化,查看打印信息:可以得到元素及其位置和大小。这样我们就实现了对元素resize的监听。除了监控元素大小、可见性、属性子节点的变化,还支持监控性能记录行为:PerformanceObserver浏览器提供性能API,记录一些时间点、某段时间、资源加载消耗等。我们希望在记录性能后立即上报,但是我们如何知道性能数据何时被记录呢?使用性能观察者。PerformanceObserver用于监控和记录性能数据的行为。一旦记录下来,就会触发一个回调,这样我们就可以在回调中上报数据了。比如性能可以使用mark方法记录某个时间点:performance.mark('registered-observer');使用measure方法记录某个时间段:performance.measure('buttonclicked','from','to');最后两个参数是时间点,不传则表示从开始到现在。我们可以使用PerformanceObserver监控它们:/4e9e751e2b32fb8afbbf559a296ccbf2~300x300.image"/>创建一个PerformanceObserver对象来监控mark(时间点)、measure(时间段)、resource(资源加载耗时),这三种记录时间的行为。然后我们用mark记录某个时间点,用measure记录按钮被点击时某段时间的数据,加载一张图片。当这些记录行为发生时,希望能够触发一个回调,并在其中上报。我们在浏览器中运行一下试试看:可以看到标记的时间点的记录,资源加载耗时,点击按钮的测量时间段的记录。这三种记录行为的数据分别打印出来:mark:imageloading:measure:使用这些数据后,可以上报做性能分析。除了元素和性能,浏览器还有一个报告监视器:ReportingObserver当浏览器运行到一个过时的(deprecation)api时,它会在控制台打印一个过时的报告:浏览器在某些情况下也会修改网页的行为干预(intervention),比如删除占用CPU过多的广告的iframe:网速慢时用占位图替换图片,点击加载:这些干预都是浏览器完成的,会打印一个控制台报告:这些介入或过时的API不是错误报告,因此无法通过错误监控获取,但这些情况对于web应用可能也很重要:例如我的网页是广告被展示了,但是当浏览器干预并为我删除了广告,我不知道。如果我知道的话,也许我可以优化iframe。比如我网页上的图片很重要,但是浏览器介入,用占位图片代替,我却不知道。如果我知道的话,也许我可以优化图像大小。那么监控是很自然的事情,所以浏览器提供了ReportingObserverAPI来监控这些报表的打印,我们就可以拿到这些报表并上传。constreportingObserver=newReportingObserver((reports,observer)=>{for(constreportofreports){console.log(report.body);//Reporting}},{types:['intervention','deprecation']});reportingObserver.observe();ReportingObserver可以监控打印过期API、浏览器干预等报告,并在回调中上报。这些是错误监控无法监控到但对理解网页运行情况很有用的数据。本文代码已上传至github:https://github.com/QuarkGluonPlasma/browser-api-exercize总结和监听用户交互行为,我们将使用addEventListener监听点击、mousedown、keydown、input等事件,但对于元素变化,XxxObserver的api应该用于非用户交互、性能记录、浏览器干预的事件。浏览器提供了这5种Observer:IntersectionObserver:监听元素可见性变化,常用于元素展示的数据采集,图片的懒加载MutationObserver:监听元素属性和子节点变化,比如ResizeObserver,可以用来制作水印thatcannotberemoved:监控元素大小变化,有两个不相关的元素:PerformanceObserver:监控性能记录的行为,上报数据ReportingObserver:监控过时的API,报告浏览器干预行为,可以让我们更全面的了解webapp相对于addEventListener添加的交互事件,这些API用的比较少,但是在特定的场景下非常有用。5个浏览器观察器你用过几个?你在什么情况下使用过它们?