前端监控的现状这几年,前端监控越来越火。目前有很多成熟的产品供我们选择使用。如下图监控平台那么多,为什么呢?想学习自研前端监控?一方面,人们需要钱。另一方面,您自己的项目需要自定义功能。前端监控的目的是提升用户体验。更快地发现异常、定位异常、解决异常。了解业务数据,指导产品升级——数据驱动思维。前端监控流程采集前端监控的第一步是数据采集。收集的信息包括环境信息、性能信息、异常信息和业务信息。环境信息环境信息是每个监测系统必不可少的内容。毕竟在排查问题的时候,需要知道它来自哪个页面,浏览器是谁,操作用户是谁……这样才能快速定位并解决问题。一般这些常见的环境信息主要包括:url:被监控的页面,可能存在性能和异常问题。获取方式为:window.location.href.ua:用户访问页面时的userAgent信息,包括操作系统和浏览器的类型和版本。获取方式为:window.navigator.userAgenttoken:记录当前用户是谁。通过记录那个用户是谁。一方面方便与用户的所有监控信息建立联系,便于数据分析;另一方面,用户的所有操作都可以通过这个标识查看,方便问题重现。性能信息页的性能直接影响用户留存率。GoogleDoubleClick研究表明,如果移动页面加载时间超过3秒,用户将放弃并离开。BBC发现,页面每加载一秒钟,用户就会减少10%,GoogleDoubleClick的研究表明,如果一个移动页面的加载时间超过3秒,用户就会放弃并离开。BBC发现,页面每加载一秒钟,用户就会减少10%。所以我们的追求就是提高页面的性能。需要监控哪些指标以提高绩效?指标分类指标有很多,我归纳为以下两个方面:网络层面和页面展示层面。从网络层面来看,涉及的指标有:重定向耗时、DNS解析耗时、TCP连接耗时、SSL耗时、TTFB网络请求耗时、数据传输耗时、资源加载time-consuming...,各个指标的解释如下表所示:页面显示等级页面显示等级指标是用户体验的几个指标,包括FP、FCP、LCP、FMP、DCL、L等。这些指标其实就是chrome浏览器。性能模块的指标(如图)。各指标的解释如下表所示。指标解决方案上述那么多指标如何获取呢?浏览器给我们留下了相应的接口——神奇的window.performance,通过它我们可以获得一系列性能相关的参数。下面以https://baidu.com为例,我们来看一下这些指标相关的参数:window.performance中timing属性的内容不就是解决上述指标所需要的值吗?看上面的属性值和对应的下面的性能接入流程图,整个过程是不是一目了然。有了以上数值,我们就一起解决以上指标:在网络层面,谷歌工程师一直在推动页面展示层面以用户为中心的性能指标,所以页面展示层面变化很大,解决方法略不同:FP和FCP通过window.performance.getEntriesByType('paint')。constpaint=window.performance.getEntriesByType('paint');constFP=paint[0].startTime,constFCP=paint[1].startTime,LCPfunctiongetLCP(){//增加一个性能条目的观察者newPerformanceObserver((entryList,observer)=>{letentries=entryList.getEntries();constlastEntry=entries[entries.length-1];observer.disconnect();console.log('LCP',lastEntry.renderTime||lastEntry.loadTime);}).observe({entryTypes:['largest-contentful-paint']});}FMPfunctiongetFMP(){letFMP;newPerformanceObserver((entryList,observer)=>{letentries=entryList.getEntries();observer.disconnect();console.log('FMP',entries);}).observe({entryTypes:['element']});}DCLdomContentLoadEventEnd–fetchStartLloadEventStart–fetchStartTTIdomInteractive–fetchStartFIDfunctiongetFID(){newPerformanceObserver((entryList,observer)=>{letfirstInput=entryList.getEntries()[0];如果(firstInput){constFID=firstInput.processingStart-firstInput.startTime;console.log('FID',FID);}observer.disconnect();}).observe({type:'first-input',buffered:true});}异常信息对于网站来说,异常信息是最致命、最影响用户体验的问题,需要监控。异常信息可以分为两类:运行时错误和接口错误。下面分别说一下这两类错误。运行时错误JavaScript运行时可能会出现的错误,可分为七种类型:语法错误、类型错误、作用域错误、引用错误、eval错误、URL错误和资源加载错误。为了捕获代码错误,需要考虑两类场景:非Promise场景和Promise场景,因为这两种场景捕获错误的策略是不同的。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('Thisisacodeerror',event);}},true)}Promise场景Promise场景的处理方式不同。当Promise被拒绝并且没有rejecthandler时,会触发unhandlerejection事件,所以通过监听unhandlerejection事件来捕获错误。exportfunctionlistenerPromiseError(){window.addEventListener('unhandledrejection',(event)=>{console.log('ThisisanerrorinthePromisescene',event);})}接口错误对于浏览器来说,所有的接口都是基于XHR和Fetch实现。为了捕捉界面中的错误,可以重写这个方法,然后利用界面返回的信息来判断当前界面的状态。下面以XHR为例说明封装过程。函数newXHR(){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);}}业务信息每个产品都会有自己的业务信息,比如用户在线时间、pv、uv、用户分布等,只有获取这些业务信息才能更清楚的了解产品的当前状态,从而使产品管理者可以更好的规划产品未来的发展方向。由于每个产品的业务信息多种多样,小伙伴可以根据自己的需要编写代码,这里就不赘述了。上报的方式无外乎两种:一种是Ajax上报;另一种是以图像的形式报告。目前很多大厂采用的上报方式都是通过1*1像素的gif图片上报。既然大家都采用了这种策略,那我们就来说说下面两个问题。为什么要用Image来报道?不存在跨域问题。因为数据服务器和后端服务器很可能在不同的域名下,如果使用Ajax处理,必须处理跨域问题,否则数据会被浏览器拦截。它不会阻止页面加载,只是新的Image对象。图片的种类很多,为什么要用gif的格式来汇报呢?其实归结为一个字——小。一张1*1px的图片,BMP结构的文件需要74字节,PNG结构的文件需要67字节,GIF结构的文件只需要43字节。同样的response,GIF比BMP可以节省41%的流量,比PNG节省35%的流量,所以选择gif做报表。分析日志上报后,需要进行清理,获取你需要的内容,存储分析内容。根据数据量的大小,可以分为单机和集群两种方式。单机访问量小,日志少的网站可以采用单机的方式进行数据分析。比如使用node读取日志文件,然后通过日志文件获取需要的信息,最后将处理后的信息存入数据库。集群中很多产品的访问量很大,日志也很多。这时候就需要使用Hadoop进行分布式处理,得到最终的处理结果。处理流程图如下:根据自己的日志级别确定自己的分析方式。就是最好的,没有必要盲目追求最好、最先进的加工方法。报警当异常类型超过一定的阈值时,需要进行报警通知,让相应的人员处理问题,及时止损。根据报警级别的不同,可选择不同的报警方式。电子邮件-一般警报。短信——严重报警,影响部分业务。电话——特别严重,例如系统宕机。
