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

一篇文章彻底搞懂前端监控

时间:2023-03-15 17:31:11 科技观察

一、前端监控的现状近年来,前端监控越来越火。目前有很多成熟的产品供我们选择使用。如下图监控平台那么多,为什么还要学习自研前端监控呢?人一方面需要钱,另一方面自己的项目需要定制功能。2、前端监控的目的是提升用户体验。更快地查找、定位和解决异常。看懂业务数据,引导产品升级——数据驱动思维。3.前端监控流程3.1采集前端监控的第一步是数据采集,采集的信息包括环境信息、性能信息、异常信息、业务信息。3.1.1环境信息环境信息是每个监测系统必不可少的内容。毕竟在排查问题的时候,需要知道它来自哪个页面,浏览器是谁,操作用户是谁……这样才能快速定位并解决问题。一般这些常见的环境信息主要包括:url:被监控的页面,可能存在性能和异常问题。获取方法为:window.location.hrefua:用户访问页面时的userAgent信息,包括操作系统和浏览器的类型和版本。获取方式为:window.navigator.userAgenttoken:记录当前用户是谁。通过记录那个用户是谁。一方面方便与用户的所有监控信息建立联系,便于数据分析;另一方面,用户的所有操作都可以通过这个标识查看,方便问题重现。3.1.2业绩信息页的好坏直接影响用户留存率。GoogleDoubleClick研究表明,如果移动页面加载时间超过3秒,用户将放弃并离开。BBC发现,页面每加载一秒钟,用户就会减少10%,GoogleDoubleClick的研究表明,如果一个移动页面的加载时间超过3秒,用户就会放弃并离开。BBC发现,页面每加载一秒钟,用户就会减少10%。所以我们的追求就是提高页面的性能。需要监控哪些指标以提高绩效?3.1.2.1指标分类指标有很多,我归纳为以下两个方面:网络层面和页面展示层面。1.网络层面从网络层面来说,涉及的指标有:重定向耗时、DNS解析耗时、TCP连接耗时、SSL耗时、TTFB网络请求耗时、数据传输耗时、资源loadingtime-consuming...,各指标解释如下表:可以就服务器是否正常工作提供反馈。TCP连接耗时指标耗时SSL连接耗时指数据安全性和完整性建立耗时TTFB网络请求耗时表示浏览器接收第一个字节的时间数据传输耗时耗时为浏览器接收内容资源加载从DOM构建完成到页面加载完成耗时2.页面显示级别页面显示级别的指标是为用户体验提出的几个指标,包括FP、FCP、LCP、FMP、DCL、L等指标其实就是chrome浏览器中性能模块的指标(如图)。各指标的解释如下表所示。指标解释FP(FirstPaint)是第一次绘制,标记浏览器呈现任何在视觉上与导航前屏幕内容不同的内容的时间点。FCP(FirstContentfulPaint)首次内容绘制,标记浏览器从DOM渲染第一个内容的时间点,内容可能是文本、图像、SVG甚至是元素。LCP(LargestContentfulPaint)最大内容渲染表示可视区域中“内容”最大的可见元素开始出现在屏幕上的时间点。FMP(FirstMeaningfulPaint)第一次有效绘制,表示页面“主要内容”开始出现在屏幕上的时间点。这是我们衡量用户加载体验的主要指标。DCL(DomContentLoaded)当HTML文档完全加载和解析时,DOMContentLoaded事件被触发,而无需等待样式表、图像和子框架加载完毕。L(onLoad)TTI(TimetoInteractive)交互时间,用于标记应用程序进入可视化渲染并能可靠响应用户输入的时间点FID(FirstInputDelay)首次输入延迟,用户与页面进行交互第一次(点击链接、点击按钮等)到页面响应交互时间3.1.2.2指标解决方案如何获取上述指标?浏览器给我们留下了相应的接口——神奇的window.performance,通过它我们可以获得一系列性能相关的参数,下面以https://baidu.com为例来看一下这些指标相关的参数:window.performance中timing属性中的内容不就是解决上述指标所需要的值吗?看上面的属性值再对应下面的性能接入流程图,整个过程一目了然。有了上面的值,我们就一起解决上面的指标:1.网络级指标计算重定向耗时redirectEnd-redirectStartDNS解析耗时domainLookupEnd-domainLookupStartTCP连接耗时connectEnd-connectStartSSL连接耗时connectEnd-secureConnectionStartTTFB网络请求耗时responseStart-requestStart数据传输耗时responseEnd-responseStart资源加载耗时loadEventStart-domContentLoadedEventEnd2.谷歌工程师一直在页面展示层面推动以用户为中心的性能指标,因此页面展示层面有变化很大,解决方法略有不同区别:1.FP和FCP通过window获取constpaint=window.performance.getEntriesByType('paint');constFP=paint[0].startTime,constFCP=paint[1]。performance.getEntriesByType('油漆')。startTime,2.LCPfunctiongetLCP(){//添加一个性能入口观察者newPerformanceObserver((entryList,observer)=>{letentries=entryList.getEntries();constlastEntry=entries[entries.length-1];observer.disconnect();console.log('LCP',lastEntry.renderTime||lastEntry.loadTime);}).观察({entryTypes:['largest-contentful-paint']});}3.FMPfunctiongetFMP(){letFMP;newPerformanceObserver((entryList,observer)=>{letentries=entryList.getEntries();observer.disconnect();console.log('FMP',entries);}).observe({entryTypes:['element']});}4.DCLdomContentLoadEventEnd–fetchStart5.LloadEventStart–fetchStart6.TTIdomInteractive–fetchStart7.FIDfunctiongetFID(){newPerformanceObserver((entryList,observer)=>{letfirstInput=entryList.getEntries()[0];if(firstInput){constFID=firstInput.processingStart-firstInput.startTime;console.log('FID',FID);}observer.disconnect();})。observe({type:'first-input',buffered:true});}3.1.3异常信息对于网站来说,异常信息是最致命的,影响用户体验。它需要被监控。异常信息可以分为两种类型:类:RuntimeError、InterfaceError。下面分别说一下这两类错误。1.运行时错误JavaScript运行时可能会出现错误,可分为七种类型:语法错误、类型错误、作用域错误、引用错误、eval错误、URL错误和资源加载错误。为了捕获代码错误,需要考虑两类场景:非Promise场景和Promise场景,因为这两种场景捕获错误的策略是不同的。1.Non-Promise场景Non-Promise场景可以通过监听错误事件来捕获错误。error事件捕获的错误分为两类:资源错误和代码错误。资源错误是指未加载的js、css、img等,这个错误只有在捕获阶段才能获取到,event.target.localName在是资源错误的时候是有值的(用来区分资源错误和代码错误);代码错误指的是最重要的是语法错误和类型错误等错误。您可以获取代码错误信息、堆栈等信息进行排查。exportfunctionlistenerError(){window.addEventListener('error',(event)=>{if(event.target.localName){console.log('这是资源错误',event);}else{console.log('this是代码错误',event);}},true)}2.Promise场景Promise场景的处理方式不同。当一个Promise被拒绝并且没有rejecthandler时,会触发unhandlerejection事件,所以通过监听unhandlerejection事件来捕获错误。exportfunctionlistenerPromiseError(){window.addEventListener('unhandledrejection',(event)=>{console.log('ThisisanerrorinthePromisescene',event);})}2.接口错误对于浏览器来说,所有的接口都是基于XHR和Fetch实现。为了捕捉界面中的错误,可以重写这个方法,然后利用界面返回的信息来判断当前界面的状态。下面以XHR为例说明封装过程。functionnewXHR(){constXMLHttpRequest=window.XMLHttpRequest;constoldXHROpen=XMLHttpRequest.prototype.open;XMLHttpRequest.prototype.open=(method,url,async)=>{//做一些自己的数据上报操作returnoldXHROpen.apply(this,arguments);}constoldXHRSend=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.send=(body)=>{//做一些自己的数据上报操作returnoldXHRSend.apply(this,arguments);}}3.1.4每个业务信息产品都会有自己的业务信息,比如用户在线时间、pv、uv、用户分布等。只有获取这些业务信息才能更清楚的了解产品的当前状态,从而让产品经理更好的规划未来的发展方向产品。由于每个产品的业务信息多种多样,小伙伴可以根据自己的需要编写代码,这里就不赘述了。3.2上报有两种上报方式:一种是Ajax上报;另一种是以图像的形式报告。目前很多大厂采用的上报方式都是通过1*1像素的gif图片上报。既然大家都采用了这种策略,那我们就来说说下面两个问题。为什么要用Image来报道?不存在跨域问题。因为数据服务器和后端服务器很可能在不同的域名下,如果使用Ajax处理,必须处理跨域问题,否则数据会被浏览器拦截。它不会阻止页面加载,只是新的Image对象。图片的种类很多,为什么要用gif的格式来汇报呢?其实归结为一个字——小。一张1*1px的图片,BMP结构的文件需要74字节,PNG结构的文件需要67字节,GIF结构的文件只需要43字节。同样的response,GIF比BMP可以节省41%的流量,比PNG节省35%的流量,所以选择gif做报表。3.3分析日志上报后,需要进行清理,获取您需要的内容,存储分析内容。根据数据量的大小,可以分为单机和集群两种方式。1.单机访问量小,日志少的网站可以采用单机的方式进行数据分析,比如使用node读取日志文件,然后通过日志文件获取需要的信息,最后存储数据库中处理过的信息。2、集群中很多产品访问量大,日志多。这时候就需要使用Hadoop进行分布式处理,得到最终的处理结果。处理流程图如下:根据自己的日志级别确定自己的分析方式。合适的才是最好的,没有必要盲目追求最好、最先进的加工方法。3.4报警当异常类型超过一定的阈值时,需要进行报警通知,让相应的工作人员处理问题,及时止损。根据报警级别的不同,可选择不同的报警方式。Email—普通报警SMS—严重报警,影响部分业务Phone—特别严重,比如系统宕机转载本文请联系放风筝的人公众号。