网友您好,针对这个问题小编今天就为大家解答做一个能对标阿里云的前端工具(上),希望通过小编的介绍对您有一定的帮忙,一起来看看吧
解决方法:

1、APM 全称是 Application Performance Monitor,即性能监控这篇文章有三个前提:从产品形态上看这肯定不是一个能够媲美阿里产品的竞品,所以抱歉我碰瓷了。
2、你可以把这里的阿里换成任何一个你在 google 用 APM 搜索到的工具。
3、但是文章最后会我会用阿里的工具对同一网站进行性能测试,看看我们两者的悬殊究竟子啊哪里。
4、很有意思的是,虽然我自己的写的这个工具相比阿里云的监测工具无比简陋,但它依然达到了我的目的帮助我发现了问题在哪。
5、从这个意义上说,这确实是一种胜利工具起点和终点是 site2share,这是一个我自己给自己写的一个工具网站,我需要知道上线后用户对它的性能感受究竟如何,所以工具因它而造,在完成对它进行性能测试的使命之后也即寿终正寝。
6、这篇文章其实是对我去年写的《性能指标的信仰危机》一文的回应
7、在那篇文章中基本都是在阐述这个工具背后的道理和设计,没有一行真实代码的落地
8、我还记的很多年前网络上盛传的一道经典前端面试题,大意是请解释从浏览器地址栏敲入 url 之后到看到页面的过程中发生了什么
9、这类问题的迷人之处在于它给了你一记响亮的大嘴巴子却又让你心服口服——原来我们对眼皮下的诸多事物都熟视无睹,以及漫不经意问题背后存在着这么大的学问题
10、在这篇文章里我要回答的问题也简单明了:我怎么知道我网站性能有多慢以及慢在哪?这个问题是网站上线之初我需要首先搞清楚的
11、有待解决的问题确定指标在大问题下有两个子问题是优先需要搞清楚,我要用什么指标来衡量快慢?我怎么排查慢的瓶颈在哪里?这两个子问题在我去年的《性能指标的信仰危机》一文中已经做出了详细说明,因为篇幅的关系,这里只陈述结论,并且两个问题的答案有千丝万缕的联系,必须放在一起聊才行简单来说,诸如 onload 或者 DOMContentLoaded 这类技术指标是远远不够的,甚至 First Contentful Paint 距离用户的实际感知依然有距离。
12、 好的指标应该尽可能的向用户靠拢,甚至是与业务深度定制的。
13、所以我建议将页面上用于承载核心内容DOM元素的出现时机作为性能的核心指标。
14、这个时机之所以关键,因为它等同于网站此时此刻才能被称之为可用
15、以网站的详情页为例,关键元素便是 .single-folder-container但着并不意味着一个指标就足够了,因为如果我们发现这个指标数值不够理想,我们无法准确定位问题在哪里
16、所以好的数据带来的效应应该是双向的:即它既能准确反映当前产品运行状态,同时通过观察数据我们也应该能得知产品存在何类问题在这个前提下,我们需要从“有潜力”的性能瓶颈中挖掘指标
17、想当然影响网站加载性能的因素有:资源加载的快慢接口响应时间那继续记录这两者的加载时间如何?要回答这个问题,我们又要继续反问自己了,这两类信息足够我们推测出问题出在哪里吗?相比单一指标而言答案是肯定的,但依然还有细化的空间
18、以资源加载为例,参考 Resource Timing 如下图所示资源加载也分为多个阶段:我们甚至可以诊断到究竟是在 DNS 解析还是 TCP 连接阶段出现了问题
19、然而我们不应该事无巨细的收集一切指标,有几个因素需要考虑:问题暴露之后是不是真的有必要解决?我有没有能力解决?比如上百毫秒的 DNS 解析时间可能是业界的好几倍,但它是否真的是我整个站点的瓶颈?采用已有的CDN解决方案是不是会比我煞费苦心的提升几百秒的时间性价比更高?我的个人经验告诉我,采集指标用的代码是有维护成本的,通常这类代码的维护成本会比业务代码成本高,成本和代码的侵入性成正比
10、成本高昂之处在于它被破坏之后难以被察觉;单元测试和回归测试更加困难回到确定指标的问题上,我们必须直面的一个现状是我们无法一次性知道我们需要什么样的数据,这很正常,确定指标就是一个是假设、验证、再假设、再验证的收敛过程。
21、尝试总比停滞能够让我们接近正确答案。

22、我们不妨开始收集上面提到的三类指标关键元素的出现时机资源加载时间接口时间接口问题前端工程师一定会落入的陷阱是只用前端的视角看待问题,而忽略了最重要的接口性能
23、对大部分人来说页面加载可能只是线性的:但实际上在 API Request 环节上,我们应该用微服务的视角来看待问题
24、一个请求从发出请求到得到响应,会经由不同的微服务用以获取数据,如果能对请求历经的每一道链路予以追踪
25、这有益于我们在线上环境中定位问题以及衡量单个微服务的效率
26、这就是 Distributed Tracing, 目前这项技术已经相当成熟了,jaegertracing,Zipkin 都是 distributed tracing 解决方案然而如果你对后端拆分服务层有所了解的话,如果想诊断单个微服务的性能在哪,我们还可以继续下钻到单个微服务中,去对比调用不同服务层方法时的性能我想表达的已经非常明显了,想要完整挖掘应用的性能瓶颈,我们应该同时对上下游进行考察,割裂视角得到的结果是有失偏颇的解决方案收集日志如果你有采集日志的经验,你应该知道日志的采集和输出是两码事
27、尤其是对于后端程序而言
28、日志既可以记录在本地文件中,也可以直接输出在控制台上,而到了线上环境则需要记录在专业的日志服务里。
29、比如 NodeJS 的开源日志类库 winston,它支持集成多种 transport,一种 transport 即为一种用于存储日志的存储方式。
30、它还支持编写自定义的 transport,目前开源社区的的 transport可选项几乎支持市面上所有主流的日志服务。
31、在 .NET CORE 中的 logging providers 也是相同的概念但这种“主动”收集日志的方式并非是最佳实践,关于构建网络应用的方法论The Twelve-Factor App曾提出,应用本身不应该考虑日志的存储,而只是保证日志以 stdout 的形式输出,由环境来负责对日志的收集与加工
32、这项提议是合理的,因为应用程序本不应该知道也无法知道它将要部署的云环境,而不同环境处理日志的方式并不相同出于 fail fast 的考虑我在开发 site2share 后端时并没有遵循这一理念,在需要进行日志采集时,我直接调用具体平台的采集方法
33、目前我的日志全部记录在 Azure Application Insights 上,所以在记录时我需要调用 Application Insights 客户端方法:AppInsightsClient.trackTrace只不过在实现层面借助 winston 代码可以变得更优雅,我们可以创建一个 logger 来达到同时兼容多个日志输出渠道的效果const logger = winston.createLogger, new winston.transports.Console ]});因为我们测试的是前端性能,且性能数据产生在消费端浏览器的网页上
34、所以我们依赖的是每个用户在访问之后由植入在页面的脚本主动上传数据Application Insights我选择 Azure Application Insights 用于存储和查询日志, 选择的其中一个原因是网站从前端到后端甚至是 DevOps 我使用的都是 Azure服务,自然官方的 Application Insights 能更好的与这些服务整合;而另一个更重要的原因是,它能为我们解决 distributed tracing 的问题
35、你需要在你的应用中植入 Application Insigths 的 SDK 才能进行日志收集,SDK支持前后端程序
36、它收集日志的方式有两种,主动收集和被动上报
37、以 Javascript 语言的 Web 应用程序为例,在页面上植入 SDK 之后它会自动收集程序运行时的报错、发出的异步请求、console.log、性能信息;你也可以调用 SDK 提供的 trackMetric、trackEvent 等主动上报自定义的指标和事件信息。
38、性能采集时我们同时利用了这两种手段我们通常将指标、日志等信息称为 telemetry ,通常这些数据会存储在不同的表中并且和其他数据淹没在一起。
39、如何将两者关联起来呢? Application Insights 将 telemetry 相互关联起来的解决方案很简单:为每一则数据提供一个唯一的上下文标识 operation_Id。
40、以用户访问一次页面为例,那么这次访问产生的数据里的 operation_Id 都叫做 xyz,那么在 Application Insights 平台上,我们便可以通过 xyz 将关联的数据查询出来| where operation_Id == "xyz"我们不仅可以将前端与前端的数据关联起来,还可以将前端与后端的数据做关联,这便是我们做 distributed tracing 的法宝
41、对于微服务应用而言,Application Insights 甚至可以为我们生成 Application Map,可视化服务间的调用过程和耗时情况

42、在过完这一小节的技术细节之后,我们可以可视化的看看我们需要哪些数据以及它们又是如何关联的资源加载指标多亏了 Performance API,在现代浏览器中收集指标变得异常简单
43、无需主动触发,浏览器在每次页面加载时就已经按照时间线将性能指标信息封装在 PerformanceEntry 对象中,事后我们只需将需要的数据筛选出来即可,比如我们关心的脚本:window.performance.getEntries.filter => initiatorType === 'script' && entryType === 'resource')根据上一小节的结论,我们也不会事无巨细的记录资源加载每一个环节的数据,在这里我重点采集资源加载的持续时间和资源加载的开始时间,这两者我们从 PerformanceEntry 上都能获取到,分别是 duration 和 fetchStart
44、因为目前在我看来前置加载以及缩短加载时间都是提升性能的有效手段
本文就讲到这里,希望能帮到您,谢谢


