一文完全搞懂前端监控

关注公众号“执鸢者”,回复“红宝书”获取“javaScript高级程序第四版(pdf)”及大量前端学习资料。

1、前端监控现状

近年来,前端监控是愈来愈火,目前已经有不少成熟的产品供咱们选择使用,以下图所示

有这么多监控平台,那为何还要学习搞前端监控?css

  • 一方面人家是要钱的
  • 另外一方面本身的项目须要定制化的功能。

2、前端监控的目的

  1. 提高用户体验
  2. 更快的发现发现异常、定位异常、解决异常
  3. 了解业务数据,指导产品升级——数据驱动的思想

3、前端监控的流程

3.1 采集

前端监控的第一个步骤就是数据采集,采集的信息包含环境信息、性能信息、异常信息、业务信息。

3.1.1 环境信息

环境信息是每一个监控系统必备的内容,毕竟排查问题的时候须要知道来自哪一个页面、浏览器是谁、操做用户是谁……,这样才能快速定位问题,解决问题。通常这些常见的环境信息主要包含:
  1. url:正在监控的页面,该页面可能会出现性能、异常问题。获取方式为:<br/>
    window.location.href<br/>
  2. ua:访问该页面时该用户的userAgent信息,包含操做系统和浏览器的类型、版本等。获取方式为:<br/>
    window.navigator.userAgent
  3. token:记录当前用户是谁。经过记录该用户是谁。<br/>
    一方面方便将该用户的全部监控信息创建联系,方便数据分析;<br/>
    另外一方面经过该标识能够查看该用户的全部操做,方便复现问题。<br/>

3.1.2 性能信息

页面的性能直接影响了用户留存率,,Google DoubleClick 研究代表:若是一个移动端页面加载时长超过 3 秒,用户就会放弃而离开。BBC 发现网页加载时长每增长 1 秒,用户就会流失 10%。,Google DoubleClick 研究代表:若是一个移动端页面加载时长超过 3 秒,用户就会放弃而离开。BBC 发现网页加载时长每增长 1 秒,用户就会流失 10%。因此咱们的追求就是提升页面的性能,为了提升性能须要监控哪些指标呢?
3.1.2.1 指标分类
指标有不少,我总结为如下两个方面:网络层面和页面展现层面。
1、网络层面
从网络层面来看涉及的指标有:重定向耗时、DNS解析耗时、TCP链接耗时、SSL耗时、TTFB网络请求耗时、数据传输耗时、资源加载耗时……,各个指标的解释以下表所示:
指标 解释
重定向耗时 重定向所耗费的时间
DNS解析耗时 浏览器输入网址后首先会进行DNS解析,其能够对服务器是否工做做出反馈
TCP链接耗时 指创建链接过程的耗时
SSL链接耗时 指数据安全性、完整性创建耗时
TTFB 网络请求耗时 表示浏览器接收第一个字节的时间
数据传输耗时 浏览器接收内容所耗费的时间
资源加载耗时 DOM构建完毕后到页面加载完毕这段时间

2、页面展现层面前端

页面展现层面的指标是针对用户体验提出的几个指标,包含FP、FCP、LCP、FMP、DCL、L等,这几个指标其实就是chrome浏览器中performance模块的指标(如图所示)。

各个指标的解释以下表所示。java

指标 解释
FP(First Paint) 首次绘制,标记浏览器渲染任何在视觉上不一样于导航前屏幕内容以内容的时间点.
FCP(First Contentful Paint) 首次内容绘制,标记浏览器渲染来自 DOM 第一位内容的时间点,该内容多是文本、图像、SVG 甚至 元素.
LCP(Largest Contentful Paint) 最大内容渲染,表示可视区“内容”最大的可见元素开始出如今屏幕上的时间点。
FMP(First Meaningful Paint) 首次有效绘制,表示页面的“主要内容”开始出如今屏幕上的时间点。它是咱们测量用户加载体验的主要指标。
DCL(DomContentLoaded) 当 HTML 文档被彻底加载和解析完成以后,DOMContentLoaded 事件被触发,无需等待样式表、图像和子框架的完成加载.
L(onLoad) 当依赖的资源所有加载完毕以后才会触发
TTI(Time to Interactive) 可交互时间,用于标记应用已进入视觉渲染并能可靠响应用户输入的时间点
FID(First Input Delay) 首次输入延迟,用户首次和页面交互(单击连接、点击按钮等)到页面响应交互的时间
3.1.2.2 指标求解
上述这么多指标该怎么获取呢?浏览器给咱们留了相应的接口——神奇的window.performance,经过该接口能够获取一些列与性能相关的参数,下面以 https://baidu.com 为例来看一下与这些指标相关的参数:

window.performance中的timing属性中的内容不就是为了求解上述指标所须要的值吗?看着上面的属性值再对应下面的performance访问流程图,整个过程是否是一目了然。

有了上面的值咱们就一块儿求解上述的指标:
1、网络层面
指标 计算
重定向耗时 redirectEnd - redirectStart
DNS解析耗时 domainLookupEnd - domainLookupStart
TCP链接耗时 connectEnd - connectStart
SSL链接耗时 connectEnd - secureConnectionStart
TTFB 网络请求耗时 responseStart - requestStart
数据传输耗时 responseEnd - responseStart
资源加载耗时 loadEventStart - domContentLoadedEventEnd

2、页面展现层面node

Google工程师一直在推进以用户为中心的性能指标,因此页面展现层面的变化较大,求解方式稍有不一样:
  1. FP和FCP

经过window.performance.getEntriesByType(‘paint’)的方式获取chrome

const paint = window.performance.getEntriesByType('paint');
const FP = paint[0].startTime,
const FCP = paint[1].startTime,
  1. LCP
function getLCP() {
    // 增长一个性能条目的观察者
    new PerformanceObserver((entryList, observer) => {
        let entries = entryList.getEntries();
        const lastEntry = entries[entries.length - 1];
        observer.disconnect();
        console.log('LCP', lastEntry.renderTime || lastEntry.loadTime);
    }).observe({entryTypes: ['largest-contentful-paint']});
}
  1. FMP
function getFMP() {
    let FMP;
    new PerformanceObserver((entryList, observer) => {
        let entries = entryList.getEntries();
        observer.disconnect();
        console.log('FMP', entries);
    }).observe({entryTypes: ['element']});
}
  1. DCL
domContentLoadEventEnd – fetchStart
  1. L
loadEventStart – fetchStart
  1. TTI
domInteractive – fetchStart
  1. FID
function getFID() {
    new PerformanceObserver((entryList, observer) => {
        let firstInput = entryList.getEntries()[0];
        if (firstInput) {
            const FID = firstInput.processingStart - firstInput.startTime;
            console.log('FID', FID);
        }
        observer.disconnect();
    }).observe({type: 'first-input', buffered: true});
}

3.1.3 异常信息

对于网站来讲,异常信息是最致命、最影响用户体验的问题,须要重点监控。对于异常信息能够分为两类:运行时错误、接口错误。下面就分别来唠一唠这两类错误。

1、运行时错误数据库

当JavaScript运行时有可能会发生错误,可归类为七种:语法错误、类型错误、范围错误、引用错误、eval错误、URL错误、资源加载错误。为了捕获代码错误,须要考虑两类场景:非Promise场景和Promise场景,由于两种场景捕获错误的策略不一样。

1.非Promise场景后端

非Promise场景可经过监听error事件来捕获错误。对于error事件捕获的错误分为两类:资源错误和代码错误。资源错误指的就是js、css、img等未加载,该错误只能在捕获阶段获取到,且为资源错误时event.target.localName存在值(用此区分资源错误与代码错误);代码错误指的就是语法错误、类型错误等这一类错误,能够获取代码错误的信息、堆栈等,用于排查错误。
export function listenerError() {
    window.addEventListener('error', (event) => {
        if (event.target.localName) {
            console.log('这是资源错误', event);
        }
        else {
            console.log('这是代码错误', event);
        }
    }, true)
}

2.Promise场景跨域

Promise场景的处理方式有所不一样,当Promise被reject且没有reject处理器的时候,会触发unhandlerejection事件,因此经过监听unhandlerejection的事件来捕获错误。
export function listenerPromiseError() {
    window.addEventListener('unhandledrejection', (event) => {
        console.log('这是Promise场景中错误', event);
    })
}

2、接口错误浏览器

对于浏览器来讲,全部的接口均是基于XHR和Fetch实现的,为了捕获接口中的错误,能够经过重写该方法,而后经过接口返回的信息来判断当前接口的情况,下面以XHR为例来展现封装过程。
function newXHR() {
    const XMLHttpRequest = window.XMLHttpRequest;
    const oldXHROpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = (method, url, async) => {
        // 作一些本身的数据上报操做
        return oldXHROpen.apply(this, arguments);
    }

    const oldXHRSend = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = (body) => {
        // 作一些本身的数据上报操做
        return oldXHRSend.apply(this, arguments);
    }
}

3.1.4 业务信息

每一个产品都会有本身的业务信息,例如用户在线时长、pv、uv、用户分布等,经过获取这些业务信息才能更加清楚的了解目前产品的情况,以便产品经理更好的去规划产品的将来方向。因为每一个产品业务信息多种多样,小伙伴本能够按照本身的需求进行撰写代码,此处我就再也不赘述。

3.2上报

对于上报的方式无外乎两种:一种是Ajax的方式上报;另外一种是经过Image的形式进行上报。目前不少大厂采用的上报方式均是经过一个1*1像素的的gif图片进行上报,既然人家都采用该种策略,那咱们就来唠一唠下面两个问题。
  • 为何采用Image的方式上报?<br/>安全

    1. 没有跨域问题。由于数据服务器和后端服务器大几率是不一样的域名,若采用Ajax的方式进行处理还要处理跨域问题,不然数据会被浏览器拦截。<br/>
    2. 不会阻塞页面加载,只需new Image对象便可。
  • 图片类型不少,为何采用gif这种格式进行上报?<br/>
    其实归结为一个字——小。对于1*1px的图片,BMP结构的文件须要74字节,PNG结构的文件须要67字节,GIF结构的文件只须要43字节。一样的响应,GIF能够比BMP节约41%的流量,比PNG节约35%的流量,因此选择gif进行上报。

3.3分析

日志上报以后须要进行清洗,获取本身所须要内容,并将分析内容进行存储。根据数据量的大小可分为两种方式:单机和集群。

1、单机<br/>

访问量小、日志少的网站能够采用单机的方式对数据进行分析,例如用node读取日志文件,而后经过日志文件中获取所须要的信息,最终将处理的信息存储到数据库中。<br/>

2、集群<br/>

不少产品的访问量很大,日志不少,此时就须要利用Hadoop进行分布式处理,获取最终处理结果,其处理流程图以下所示:

根据本身的日志量级决定本身的分析方式,合适的就是最好的,不用一味追求最优的、最早进的处理方式。

3.4报警

当异常类型超多必定阈值以后须要进行报警通知,让对应的工做人员去处理问题,及时止损。根据报警的级别不一样,能够选择不一样的报警方式。
  1. 邮件——普通报警
  2. 短信——严重报警,已影响部分业务
  3. 电话——特别严重,例如系统已宕机

1.若是以为这篇文章还不错,来个分享、点赞、吧,让更多的人也看到

2.关注公众号执鸢者,领取学习资料,按期为你推送原创深度好文

参考

http://www.alloyteam.com/2020...
https://www.colabug.com/2019/...
image

相关文章
相关标签/搜索