一文摸清前端监控实践要点(一)性能监控

作者&投稿:驷炊 (若有异议请与网页底部的电邮联系)
~ 前言

前端监控是一个历史长久的话题了,目前一提到监控平台,大部分开发同学想到的是什么?没错,sentry,那么我们这篇文章为什么要自己搞呢?

很简单,团队项目要钱呐,数据量越大费用越高;并且不方便团队做自己的数据分析以及埋点设计,还有前端后端全链路的一个API请求链路分析也不方便;另一方面,自己搞一个是自己的技术提升,只会用不知怎么回事,那怎么行~

所以这部整理了一下自己在团队中自建浏览器环境下前端监控的实践经验,整理成文分享出来:

一般来说,前端搭建监控体系,可以概括为为了做两件事:如何及时发现问题、如何快速定位问题,而为了解决这两个问题,前端监控体系需要关注的点可以拆分为如下:

页面的性能情况:包括各阶段加载耗时,一些关键性的用户体验指标等

用户的行为情况:包括PV、UV、访问来路,路由跳转等

接口的调用情况:通过http访问的外部接口的成功率、耗时情况等

页面的稳定情况:各种前端异常等

数据上报及优化:如何将监控捕获到的数据优雅的上报

如果全部内容都放在一篇文章中进行说明,会导致过于冗长且失去层级,所以本篇中只介绍前端监控的第一部分:页面性能监控;

页面的性能情况

我们都听说过性能的重要性。但当我们谈起性能,以及让网站"速度提升"时,我们具体指的是什么?

其实性能是相对的:

某个网站可能对一个用户来说速度很快(网速快,设备强大的情况下),但可能对另一个用户来说速度很慢(网速慢,设备低端的情况下)。

两个网站完成加载所需的时间或许相同,但其中一个却显得加载速度更快(如果该网站逐步加载内容,而不是等到最后才一起显示)。

一个网站可能看起来加载速度很快,但随后对用户交互的响应速度却很慢(或根本无响应)。

因此,在谈论性能时,重要的是做到精确,并且根据能够进行定量测量的客观标准来论及性能。这些标准就是指标。

而前端性能监控,就是要监测页面的性能情况,将各种的性能数据指标量化并收集

W3C标准化

官方地址:NavigationTimingLevel2

为了帮助开发者更好地衡量和改进前端页面性能,W3C性能小组引入了NavigationTimingAPI,实现了自动、精准的页面性能打点;开发者可以通过window.performance属性获取。

下图是W3C第一版的NavigationTiming的处理模型。

上图Level1的规范,2012年底进入候选建议阶段,至今仍在日常使用中;但是在W3C的议程上,它已经功成身退,让位给了精度更高,功能更强大,层次更分明的Level2(处理模型如下图)。比如独立划分出来的ResourceTiming,使得我们可以获取具体资源的详细耗时信息。

w3clevel2扩充了performance的定义,并增加了PerformanceObserver的支持。

图中指标的解读可以在https://developer.mozilla.org/zh-CN/docs/Web/API/PerformanceTiming中查看

web-vitals

web-vitals是一个google开源的一个用以衡量性能和用户体验的工具,我将它放在这里介绍,是因为下文的性能关键指标获取中,有的会介绍通过这个开源插件进行获取的方法;

相比于我们自己手动写,它会替我们覆盖很多兼容和特殊的场景;

它支持了这些指标:https://web.dev/metrics/

获取PerformanceTiming

既然已经有了W3C标准化定义的PerformanceTiming,那我们自然就要获取它并予以活用,用来计算获取我们所需要的性能指标

而对于上文提到的W3CLevel1和W3CLevel2;建议先使用W3CPerformanceTimelineLevel2的High-ResolutionTime,时间精度可以达毫秒的小数点好几位,当浏览器不支持时获取结果为空数组。所以还得向下兼容使用W3CLevel1;

let?t?=?window.performance.timing;//?W3C?Level1??(目前兼容性高,仍然可使用,未来可能被废弃)。if?(typeof?window.PerformanceNavigationTiming?===?'function')?{??try?{????//?W3C?Level2??PerformanceNavigationTiming????//使用了High-Resolution?Time,时间精度可以达毫秒的小数点好几位。????let?nt2Timing?=?performance.getEntriesByType('navigation')[0];????if?(nt2Timing)?{??????t?=?nt2Timing;????}??}?catch?(err)?{????console.log(err);??}}

以用户为中心的性能指标

什么叫以用户为中心的性能指标呢?其实就是可以直接的体现出用户的使用体验的指标;目前Google定义了FCP、LCP、CLS等体验指标,已经成为了目前业界的标准;对于用户体验来说,指标可以简单归纳为加载速度、视觉稳定、交互延迟等几个方面;

加载速度决定了用户是否可以尽早感受到页面已经加载完成

视觉稳定衡量了页面上的视觉变化对用户造成的负面影响大小

交互延迟决定了用户是否可以尽早感受到页面已经可以操作

而针对于上面三个方面,我们可以采集以下多种指标进行衡量

白屏(FP)、灰屏(FCP)

W3C标准化在w3c/paint-timing定义了首次非网页背景像素渲染(fp)(白屏时间),当浏览器通过performance.getEntriesByType('paint')取不到时,再去取performance.timing中的计算值。

let?fp?=?0;?//白屏时间??首次非网页背景像素渲染const?paint?=?performance.getEntriesByType('paint');//?https://github.com/w3c/paint-timingif?(paint.length?!==?0)?{??//判断浏览器是否支持paint??fp?=?paint[0].startTime;}?else?{??fp?=?t.responseEnd?-?t.fetchStart;??//?这里的?t?是上一个标题内容定义的?PerformanceTiming?哦}

paint还定义了一个首次内容渲染(fcp)(灰屏时间),这里简单说一下获取方式:

我们可以自己手动写一个FCP获取:

new?PerformanceObserver((entryList)?=>?{??for?(const?entry?of?entryList.getEntriesByName('first-contentful-paint'))?{????console.log('fcp',?entry);??}}).observe({?type:?'paint',?buffered:?true?});

也可以使用google的web-vitals:

import?{getFCP}?from?'web-vitals';//?当?FCP?可用时立即进行测量和记录。getFCP(console.log);

FP首次绘制:页面视觉首次发生变化的时间点。FP不包含默认背景绘制,但包含非默认的背景绘制。

FCP首次内容绘制:首次绘制任何文本、图像、非空白canvas或者SVG的时间点。

FP和FCP的区别:FCP是首次绘制来自DOM的有效内容的时间点;所以FP可能=FCP,也可能先于FCP。大部分情况下得到的值两者相等;

但假如,我给单页面应用的body元素加了一个背景色,那么FP记录的时间就是开始绘制带背景色的body的时间点,而FCP记录的则是body生成之后,首次绘制来自DOM的有效内容的时间点,这个时候FP的时间点就先于FCP

首次有效绘制(FMP)(首屏)

有的同学或许会疑问,上面的灰屏时间,在我看来就是首屏的时间呀?为什么还需要单独开一栏说呢?其实不然,我们再回忆一次灰屏的定义:FCP是首次绘制任何文本、图像、非空白canvas或者SVG的时间点。注意,这里的用词是任何;也就意味着,如果按照这种逻辑,客户端渲染了一个字的时间点,就认为了首屏时间的时间点所在,

FMP首次有效绘制,我们可以定义为页面渲染过中元素增量最大的点,因为元素增量最大的时候,页面主要内容也就一般都渲染完成了;

目前W3C还没有关于FMP的标准化计算定义;但是W3C关于首屏统计已经进入了提议阶段,坐等W3C再次标准化。可以在github上看到最新的进展,详见w3c/paint-timing。

如果想系统化首屏的计算,可以参考阿里ARMS的FMP文章,或者可以使用手动在代码中埋点的方式进行计算;

最大内容绘制(LCP)

LCP是页面内首次开始加载的时间点,到可视区域内最大的图像或者文本块完成渲染的相对时间,是一个以用户为中心的性能指标,可以测试用户主观感知到的页面加载速度,因为最大内容绘制完成时,往往可以认为页面将要加载完成

通常来说,为了提供良好的用户体验,我们应该努力将最大内容绘制控(LCP)制在2.5秒或以内。

我们可以自己手动写一个LCP获取:

new?PerformanceObserver((entryList)?=>?{??const?entries?=?entryList.getEntries();??const?entry?=?entries[entries.length?-?1];??console.log('lcp',?entry);}).observe({?type:?'largest-contentful-paint',?buffered:?true?});

也可以使用google的web-vitals:

import?{?getLCP?}?from?'web-vitals';//?当?LCP?可用时立即进行测量和记录。getLCP(console.log);

首次输入延迟(FID)

FID是从用户第一次与页面交互(例如当他们单击链接、点按按钮或使用由JavaScript驱动的自定义控件)直到浏览器对交互作出响应,并实际能够开始处理事件处理程序所经过的时间。

通常来说,我们可以认为,FID时间在100ms内的能让用户得到良好的使用体验

我们可以手动写一个FID获取:

new?PerformanceObserver((entryList)?=>?{??const?entries?=?entryList.getEntries();??const?entry?=?entries[entries.length?-?1];??const?delay?=?entry.processingStart?-?entry.startTime;??console.log('FID:',?delay,?entry);}).observe({?type:?'first-input',?buffered:?true?});

也可以使用google的web-vitals:

import?{?getFID?}?from?'web-vitals';//?当?FID?可用时立即进行测量和记录。getFID(console.log);

累计布局偏移(CLS)

CLS是测量整个页面生命周期(页面可见性变成隐藏)内发生的所有意外布局偏移中最大一的布局偏移分数。;每当一个已渲染的可见元素的位置从一个可见位置变更到下一个可见位置时,就发生了布局偏移。

CLS会衡量在网页的整个生命周期内发生的所有意外布局偏移的得分总和。

简单点说,就是正在阅读文章时,突然页面上某些内容发生了改变;或者你正要点击一个链接或一个按钮,但在手指落下的瞬间,哟?按钮来了一拨灵性走位,导致你点到了别的东西;可以看下图:

通常来说,我们应该将CLS分数控制在0.1?或以下

我们可以手动写一个FID获取:

let?clsValue?=?0;let?clsEntries?=?[];let?sessionValue?=?0;let?sessionEntries?=?[];new?PerformanceObserver((entryList)?=>?{??for?(const?entry?of?entryList.getEntries())?{????//?只将不带有最近用户输入标志的布局偏移计算在内。????if?(!entry.hadRecentInput)?{??????const?firstSessionEntry?=?sessionEntries[0];??????const?lastSessionEntry?=?sessionEntries[sessionEntries.length?-?1];??????//?如果条目与上一条目的相隔时间小于?1?秒且??????//?与会话中第一个条目的相隔时间小于?5?秒,那么将条目??????//?包含在当前会话中。否则,开始一个新会话。??????if?(????????sessionValue?&&????????entry.startTime?-?lastSessionEntry.startTime?<?1000?&&????????entry.startTime?-?firstSessionEntry.startTime?<?5000??????)?{????????sessionValue?+=?entry.value;????????sessionEntries.push(entry);??????}?else?{????????sessionValue?=?entry.value;????????sessionEntries?=?[entry];??????}??????//?如果当前会话值大于当前?CLS?值,??????//?那么更新?CLS?及其相关条目。??????if?(sessionValue?>?clsValue)?{????????clsValue?=?sessionValue;????????clsEntries?=?sessionEntries;????????//?将更新值(及其条目)记录在控制台中。????????console.log('CLS:',?clsValue,?clsEntries);??????}????}??}}).observe({?type:?'layout-shift',?buffered:?true?});

也可以使用google的web-vitals:

import?{getCLS}?from?'web-vitals';//?在所有需要汇报?CLS?的情况下//?对其进行测量和记录。getCLS(console.log);

以技术为中心的性能指标

什么叫以技术为中心的性能指标呢?

我们再来看上面这张之前放过的图,这是W3CPerformanceTimelineLevel2的模型图,图中很多的时间点、时间段,对于用户来说或许并不需要知道,但是对于技术人员来说,采集其中有意义的时间段,做成瀑图,可以让我们从精确数据的角度对网站的性能有一个定义,有一个优化的方向;

关键时间点字段描述计算公式备注FP白屏时间responseEnd-fetchStart从请求开始到浏览器开始解析第一批HTML文档字节的时间。TTI首次可交互时间domInteractive-fetchStart浏览器完成所有HTML解析并且完成DOM构建,此时浏览器开始加载资源。DomReadyHTML加载完成时间也就是DOMReady时间。domContentLoadEventEnd-fetchStart单页面客户端渲染下,为生成模板dom树所花费时间;非单页面或单页面服务端渲染下,为生成实际dom树所花费时间'Load页面完全加载时间loadEventStart-fetchStartLoad=首次渲染时间+DOM解析耗时+同步JS执行+资源加载耗时。FirstByte首包时间responseStart-domainLookupStart从DNS解析到响应返回给浏览器第一个字节的时间关键时间段字段描述计算公式备注DNSDNS查询耗时domainLookupEnd-domainLookupStart如果使用长连接或本地缓存,则数值为0TCPTCP连接耗时connectEnd-connectStart如果使用长连接或本地缓存,则数值为0SSLSSL安全连接耗时connectEnd-secureConnectionStart只在HTTPS下有效,判断secureConnectionStart的值是否大于0,如果为0,转为减connectEndTTFB请求响应耗时responseStart-requestStartTTFB有多种计算方式,相减的参数可以是requestStart或者startTimeTrans内容传输耗时responseEnd-responseStart无DOMDOM解析耗时domInteractive-responseEnd无Res资源加载耗时loadEventStart-domContentLoadedEventEnd表示页面中的同步加载资源。

采集了上述的关键时间段后,我们可以做出一次页面加载的具体性能瀑图,我们可以根据这个图分析性能优化的方向;

其它也有意义的指标静态资源加载

我们可以获取每次加载时所访问的静态资源,将收集到的静态资源做成瀑图等分析图形,来找出导致静态资源加载时间过长的问题所在。

let?fp?=?0;?//白屏时间??首次非网页背景像素渲染const?paint?=?performance.getEntriesByType('paint');//?https://github.com/w3c/paint-timingif?(paint.length?!==?0)?{??//判断浏览器是否支持paint??fp?=?paint[0].startTime;}?else?{??fp?=?t.responseEnd?-?t.fetchStart;??//?这里的?t?是上一个标题内容定义的?PerformanceTiming?哦}0

静态资源加载的缓存命中率

很多的一些资源,比如img图片等,在用户加载后这些资源就会被缓存起来,再下一次进入时判断缓存类型、是否过期来决定是否使用缓存;那么我们就可以统计每一次用户进入时的一个缓存命中率;

那么,如何判断用户的资源是否命中了缓存呢?,其实很简单,如果静态资源被缓存了,它具有以下两个特征:

静态资源的duration为0;

静态资源的transferSize不为0;

根据上面这两个特征,我们就可以计算每次加载的缓存命中率:

let?fp?=?0;?//白屏时间??首次非网页背景像素渲染const?paint?=?performance.getEntriesByType('paint');//?https://github.com/w3c/paint-timingif?(paint.length?!==?0)?{??//判断浏览器是否支持paint??fp?=?paint[0].startTime;}?else?{??fp?=?t.responseEnd?-?t.fetchStart;??//?这里的?t?是上一个标题内容定义的?PerformanceTiming?哦}1

PS:跨域资源(CDN)

获取页面资源时间详情时,有跨域的限制。默认情况下,跨域资源以下属性会被设置为0

redirectStart

redirectEnd

domainLookupStart

domainLookupEnd

connectStart

connectEnd

secureConnectionStart

requestStart

responseStart

transferSize

如果想获取资源的具体时间,跨域资源需要设置响应头Timing-Allow-Origin

对于可控跨域资源例如自家CDN,Timing-Allow-Origin的响应头origins至少得设置了主页面的域名,允许获取资源时间

一般对外公共资源设置为Timing-Allow-Origin:*。

分析得出的指标

分析得出的指标,意味着不是一次采集就能得到的指标数据,而指的是对于整个应用来说,对采集上来的众多数据进行分析而得出的指标情况;

首次加载跳出率:第一个页面完全加载前用户跳出率;

慢开比:完全加载耗时超过5s的PV占比;

多维度分析:对地域、网络、页面等多个维度下的性能情况;

参考阅读

前端监控-首屏统计的前世今生

web-vitals

W3Cpaint-timing

Google文档-指标

Lighthouse计算源码

原文:https://juejin.cn/post/7097157902862909471




一文摸清前端监控实践要点(一)性能监控
而前端性能监控,就是要监测页面的性能情况,将各种的性能数据指标量化并收集W3C标准化 官方地址:NavigationTimingLevel2 为了帮助开发者更好地衡量和改进前端页面性能,W3C性能小组引入了NavigationTimingAPI,实现了自动、精准的页面性能打点;开发者可以通过window.performance属性获取。 下图是W3C第一版的NavigationTiming的处理...

男子入室盗窃因拍死一只蚊子留下 DNA 被抓,还有哪些意想不到的破案手 ...
有一次看法制类节目时,就看到过类似的真实案例,广西桂林警方在破获多起入室盗窃案是就利用了犯罪嫌疑人的鞋印,因为线索特别少,这几起案件的现场只能提取到鞋印,办案人员利用鞋印大致判断出嫌疑人的身高、体型来缩小范围,最后通过监控锁定犯罪嫌疑人并抓获,尽显能力过硬!除了鞋印,破获案件最多的方法还...

假如我是一名客服经理我应该怎么做?要一套演讲稿,快!谢了!
一是社区经理渠道要加强维护指标达标、做好服务质量提升,实行“分田到户,守土有责”,强化前端员工树立维护也是经营、维护也是服务意识;将运维优势转化为营销优势。 实现社区经理“三合一”的模式;抓社区经理营销系统应用,指导、培训、建立社区经理的骨干(核心)队伍,利用社区经理独立的工作方式和日积月累的客户关系进行...

谁知道濒临灭绝的动植物的中英文和简介?(至少10个)
中国珍稀濒危植物【荷叶铁线蕨】【学 名】 Adiantum reniforme L. var. sinense Y. X. Ling 【中文学名】 荷叶铁线蕨 【科 别】 Adiantaceae 铁线蕨科 【濒危类别】 濒危 【保护级别】 2级 【现 状】 仅存于四川万县和石柱县,因筑路\\采挖作药用,现数量极少,陷入濒危 【分布省县】 四川万县...

智慧消防指的是什么?
智慧消防就是智能消防系统是将GPS(全球卫星定位系统)、GIS(地理信息系统)、GSM(无线移动通信系统)和计算机、网络等现代高新技术集于一体的智能消防无线报警网络服务系统。它成功地解决了电信、建筑、供电、交通等公共设施建设协调发展的问题;由于消防指挥中心与用户单位联网,改变了过去传统、落后和被动的...

万能年终工作总结范文大全简短
我注重以工作任务为牵引,依托工作岗位学习提高,通过观察、摸索、查阅资料和实践锻炼,较快地完成任务。另一方面,问书本、问同事,不断丰富知识掌握技巧。在各级领导和同事的帮助指导下,不断进步,逐渐摸清了工作中的基本情况,找到了切入点,把握住了工作重点和难点。 (二)爱岗敬业、扎实工作、不怕困难、勇挑重担,热情...

中保登首批业务规则正式发布有何意义?
第一,通过规范产品集中登记流程,发挥集中性登记交易场所的市场汇聚作用,全面摸清风险底数。业务制度明确了保险资管产品登记的内容,要求对保险资管产品的产品信息、份额信息及其变动情况进行集中登记。海量的登记交易信息有助于创建丰富的监管指标体系和风险预警体系,实现监管维度的全面覆盖和深度穿透。第二,...

怎样挖掘自己的优点?
不去尝试新的东西,不去接触新的事物,怎么可能摸清前路。正所谓量变引起质变,很多时候灵感也是在无数实践的基础上迸发出来的。在第二点中我想给大家一个小贴士叫做“经验”。虽说事非经过不知难,但毕竟时间有限,有时吸取别人的经验教训也显得尤为重要。多去接触每个方面的“过来人”,可以帮我们节省...

如何提高中等职业学校学生的就业能力
2、创业园区要对所有学生平等开放,尽量为更多的学生创造学习和实践的机会。但从学生专业能力形成和园区容纳能力考虑,进入创业园区的应为二、三年级学生。学生毕业后必须离开园区。学生进入园区创业经营实习必须向管委会提交书面申请和项目可行性报告,经管委会审批后方可进入园区从事生产经营实习活动。3、创业园区要为学生...

"旋风少女"的拼音大写怎么写?
XUAN FENG SHAO NV 1、旋毛虫 造句:为摸清西昌市生猪旋毛虫感染的强度和分布情况,我们采用酶联免疫吸附试验(ELISA)法和常规压片镜检法对从我市4个定点屠宰场采集的生猪血清和膈肌进行检验。解释:线形动物,身体小,长圆形,前端尖而细。常寄生在人和哺乳动物的小肠内。旋毛虫由小肠转移到...

曲江区17866601503: 如何发挥网站性能监控最大化 -
宰匡氯普: 1. 网络性能互通性 互通性是性能监控工具的基本功能,能够从数据中心内各种硬件与部件中访问与读取数据源.在部署了同一厂商产品线设备的同质环境内,利用集成在硬件中的内置挂钩,监控工具可以发挥极大优势.在异质环境下,监控则...

曲江区17866601503: 如何测试监控系统的性能 -
宰匡氯普: 监控器从设计完成之后, 分别对系统性能测试,测试项目为can总线接收、数据显示、gps接收、 gsm发送、接收和故障诊断等功能.

曲江区17866601503: 监控系统功能分为哪三个部分?
宰匡氯普: 1、前端采集部分 前端采集部分多由一台或多台摄像机及 红外灯 ;声音采集设备、防护罩等组成,主要是为了采集画面、声音、报警信息和状态信息.摄像机录制了...

曲江区17866601503: 如何快速高效地进行APP性能监测工作? -
宰匡氯普: APP性能监控是将APP运行时产生的性能数据进行获取及处理和分析,通过平台发现应用对用户影响最大的性能问题并通过云端对性能数据进行存储、分析,以邮件、微信方式推送.APP性能监控是模拟用户真实操作场景对APP在实际运行中的性能数据,比如:响应耗时、数据流量、CPU占用率等,进行持续性监控.想要快速高效地对APP进行性能监测那你可以了解下听云APP,通过植入探针主动探测移动应用性能,采集真实用户移动设备上的应用性能,通过实时呈现多维立体的性能数据并自动分析,降低APP上线后的维护成本,帮助开发者及时发现应用性能隐患.

曲江区17866601503: 出租屋视频门禁报警系统有哪些性能要求?
宰匡氯普: 出租屋视频门禁报警系统的性能要求 Ø 大容量:为满足不同规模的出租屋视频门禁报警系统项目管理要求,村级规模项目要求同一平台下支持2000栋楼、10万人口及10个...

曲江区17866601503: 要做好性能测试,该掌握些什么? -
宰匡氯普: 这类问题之前也被问到很多次了,所以这次干脆整理一下,发个主题供同行们参考.如果需要补充,也欢迎大家留言一起讨论. 如果想真的做好性能测试,需要学习的东西还是比较多的.简单列一下吧. 1. 精通性能测试的基本概念...

曲江区17866601503: 如何判断高清监控摄像机的性能 -
宰匡氯普: 在检测宽动态功能时,需要观察亮区与暗区之间过渡是否清晰自然

曲江区17866601503: Linux服务器整体性能监控攻略 Linux服务器如何监控整体性能? -
宰匡氯普: Linux服务器性能监测是很重要的工作,服务器运行应该提供最有效的系统性能.当服务器系统性能突然低于平均应有的情况,问题可能来自在执行的进程、内存的使用率、磁盘的性能、网络流量和CPU 的压力.在预算短缺的今天,理解如何优...

曲江区17866601503: 一般性能监控是指什么,听云的怎么样? -
宰匡氯普: 性能监控,基于真实业务场景与用户行为的云端压力测试技术.快速实现对全链路和全部业务的压力测试,分布式测试等,听云性能监控,不仅对各种网络情况、第三方调用API等多维度进行监控外,还增加了对App交互性能的检测,深入追踪崩溃及错误,功能齐全,可以去测试一下.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网