性能指标都是些什么鬼?

本文讲的是性能指标都是些什么鬼?,


原文地址:Performance metrics. What’s this all about?
原文作者:Artem Denysov
译文出自:掘金翻译计划
本文永久链接:https://github.com/xitu/gold-miner/blob/master/TODO/performance-metrics-whats-this-all-about.md
译者:llp0574
校对者:ppp-manlampui

测量页面的加载性能是一项艰难的任务。因此 Google Developers 正和社区一起致力于渐进式网页指标(Progressive Web Metrics,简称 PWM’s)。

PWM’s 都是些什么,我们为什么需要它们?

先来讲一点关于浏览器指标的历史。

此前我们有两个主要的点(事件)来测量性能:

DOMContentLoaded — 页面加载时触发,但脚本文件刚刚开始执行。

load 事件在页面完全加载后触发,此时用户已经可以使用页面或应用。

举个例子,如果我们看一下 reddit.com 的跟踪时间轴(Chrome 的开发者工具可以帮助我们用蓝色和红色的垂直线来标记那些点),就可以明白为什么这些指标不是那么有用了。

时至今日,我们也可以看到 window.onload 并没有像以前那样真实反映出用户的感知。

参考:Steve SoudersMoving beyond window.onload() (2013)

确实,DOMContentLoaded 的问题在于解析和执行 JavaScript 的时间,如果脚本文件太大,那么这个时间就会非常长。比如移动设备,在 3G 网络的限制下测量跟踪时间轴,就会发现要花费差不多十秒才能到达 load 点。

另一方面,load 事件太晚触发,就无法分析出页面的性能瓶颈。

所以我们能否依赖这些指标?它们到底给我们提供了什么信息?

而且最主要的问题是,从页面开始加载直至加载完成,用户如何感知这个过程?

为什么加载感知会如此重要?可以参考 Chrome Developers 上的一篇文章:Leveraging the Performance Metrics that Most Affect User Experience,再次强调了加载问题。

看一下下方柱状图,X 轴展示了加载时间,Y 轴展示了体验到加载时长在特定时间区间里的用户的相对数量,你就可以明白不是所有用户的体验加载时间都会小于两秒。

因此在我们的试验里,17 秒左右的 load 时间在获取用户感知加载这方面是没有什么价值的。用户在这 17 秒里到底看到了什么?白屏?加载了一半的页面?页面假死(用户无法点击输入框或滚动)?如果这些问题有答案的话:

  1. 可以改善用户体验
  2. 给应用带来更多的用户
  3. 增加产品所有者的利益(用户、消费者、钱)


所以,大家都在尝试解读用户的想法并预测用户在这 17 秒的加载时间里会想些什么。

  1. “它正在运行吗?”

我的网页浏览开始了吗(服务器有回应,等等)?
Has my navigation started successfully (the server has responded, etc.)?

  1. “它有用吗?”

页面上是否有足够关键的内容使我能够理解?

  1. “它可以使用了吗?”

我能不能和页面互动了呢?还是它依旧处于加载状态?

  1. “用户体验良好吗?”

是否没有滚动卡顿、动画卡顿、无样式内容闪烁和缓慢的 Web 字体文件加载等问题出现,让我感到惊喜?



如果 DOMContentLoaded 或者 load 指标不能回答这些问题,那么什么指标可以回答?

渐进式网页指标(Progressive Web Metrics)

PWM’s 的指标列表目的在于帮助检测性能瓶颈。除开 load 和 DOMContentLoaded,PWM’s 给开发者提供了更多更详细的关于页面加载的信息。

下面让我们用 reddit.com 的跟踪时间轴来探究一下 PWM’s,并尝试弄明白每个指标的意思。


首次绘制(First Paint,FP)

我曾经说我们只有两个指标,这其实不太准确。(Chrome)开发者工具还给我们提供了一个指标 - FP。这个指标表示页面绘制的时间点,换句话说它表示当用户第一次看到白屏的时间点(下面是 msn.com 的 FP 截屏)。可以在规范说明里阅读更多相关内容。

想弄明白它是如何工作的话,作为例子,我们可以看一下 Chromium 图层的底层原理。

FP 事件在图层进行绘制的时候触发,而不是文本、图片或 Canvas 出现的时候,但它也在列表里给出了一些开发者尝试使用的信息。

但它并不是标准指标,所以测量就变得非常棘手。因此用到了一些不同的 “取巧” 技术,比如:

  • 附加 requestAnimationFrame 使用
  • 捕捉 CSS 资源加载
  • 甚至使用 DOMContentLoaded 和 load 事件(它们的问题之前已经讲过)

但是,尽管做出了这些努力,它仍然不具有太大的价值,因为文本、图片和 Canvas 可能在 FP 事件触发没多久就会进行绘制,而这些则会被诸如页面权重、CSS 或 JavaScript 资源大小等性能瓶颈所影响。

这个指标不属于 PWM 的一部分,但它对于理解下面将要讲到的指标很有帮助。

所以需要其他一些指标来表示真实的内容绘制。

首次内容绘制(First Contentful Paint,FCP)

这是当用户看见一些“内容”元素被绘制在页面上的时间点。和白屏是不一样的,它可以是文本的首次出现,或者 SVG 的首次出现,或者 Canvas 的首次出现等等。

因此,用户可能会产生疑问,它正在运行吗? 页面是否在他(她)键入 URL 并按 enter 键后开始加载了呢?

继续看一下 Chromium,FCP 事件在文本(正在等待字体文件加载的文本不计算在内)、图片、Canvas 等元素绘制期间就已经被触发了。因此,FP 和 FCP 的时间差异可能从几毫秒到几秒不等。这个差别甚至可以从上面的图片中看出来。这就是为什么用一个指标来表示真实的首次内容绘制是有价值的。

你可以从这里阅读所有的规范说明。

FCP 指标如何对开发者产生价值?

如果首次内容绘制耗时太长,那么:

  • 你的网络连接可能有性能问题
  • 资源太过庞大(如 index.html),传输它们消耗太多时间

阅读 Ilya Grigorik 写的 High Performance Browser Networking 了解更多关于网络性能的问题,消除这些因素的影响。


首次有意义绘制(First Meaningful Paint,FMP)

这是指页面主要内容出现在屏幕上的时间点,因此,它有用吗?

主要内容是什么?

  • 博客的标题和文本
  • 搜索引擎的搜索文本
  • 对于电子商务产品来说重要的图片

展示的时候。

但如果展示的是

  • 下拉菜单或类似的东西
  • 无样式内容闪烁(FOUC)
  • 导航条或页面标题

则不计算在主要内容之内。

FMP = 最大布局变化时的绘制

基于 Chromium 的实现,这个绘制是使用 LayoutAnalyzer 进行计算的,它会收集所有的布局变化,当布局发生最大变化时得出时间。而这个时间就是 FMP。

你可以从这里阅读所有的规范说明。

FMP 指标如何对开发者产生帮助?

如果主要内容很久都没有展示出来,那么:

  • 太多资源(图片、样式、字体、JavaScript)有较高的加载优先级,因此,它们阻塞了 FMP

我不想重复太多已有的用来提升这些瓶颈的实践方法,给大家留出一些链接:

从这些文章里可以找到所有需要的信息。


视觉上准备好

当页面看上去“接近”加载完成,但浏览器还没有执行完所有脚本文件的状态。


预计输入延迟

这个指标意在估计应用对于用户输入的响应有多流畅。

但在深入研究前,我想通过解释一些术语以便大家在理解上同步。

长任务

浏览器底层将所有用户输入打包在一个任务里(UI 任务),并在主线程中将它们放到一个队列里。除此之外,浏览器还必须在页面上解析、编译和执行 JavaScript 代码(应用任务)。如果每个应用任务要耗费很长时间的话,那么用户输入任务就可能在其他任务结束前受到阻塞。因此它就会延迟与页面的交互,页面行为就会变得卡顿有延迟。

简单来说,长任务就是指耗时大于 50 毫秒的解析、编译和执行 JavaScript 代码块。

你可以从这里阅读所有的规范说明。

长任务 API 已经在 Chrome 里实现,并用作测量主线程的繁忙程度。

回到预计输入延迟,用户会假设页面响应很快,但如果主线程正忙于处理各个长任务,那么就会让用户不满意。对于应用来说,用户体验至关重要,可以从 Measure Performance with the RAIL Model 这篇文章里阅读关于这种类型的性能瓶颈如何进行性能提升。


首次交互

交互 - 它可以使用了吗? 是的,这是当用户看见视觉上准备好的页面时提出的问题,他们希望能与页面产生交互。

首次交互发生需满足以下条件:

首次交互 - 这个指标可以拆分成两个指标,首次交互的时间(Time to First Interactive,TTFI)和首次持续交互的时间(Time to First Consistently Interactive,TTCI)。

拆分的原因在于:

  • 当 UI 响应良好时,定义最小程度的交互,但如果响应不好也可以接受
  • 当网站有着完整且令人愉悦的交互,并严格遵循 RAIL 的指导原则时

TTCI

使用逆序分析,从追踪线的尾端开始看,发现页面加载活动保持了 5 秒的安静并且再无更多的长任务执行,得到了一段叫做安静窗口的时期。安静窗口之后及第一个长任务(从安静期结束后开始算)之前的时间就是TTCI。

TTFI

这个指标的定义和 TTCI 有一点不同。我们从头至尾来分析跟踪时间轴。在 FMP 发生后应该有 3 秒的安静窗口。这个时间已经足够说明页面对于用户来说是可交互的。但可能会有长任务在这个安静窗口期间或之后开始执行,它们可以被忽略。

长任务 - 距离 FMP 很远执行的任务,并由 250ms 的执行时间期间(信道大小)和在信道大小前后的 1 秒安静期分隔开来。这个示例任务有可能是第三方广告或者分析脚本。

有时长于 250 毫秒的“长任务”会对页面有严重的影响。

比如检测adblock

你可以从这里阅读所有的规范说明。

TTFI 和 TTCI 指标如何对开发者产生帮助?

当线程长时间处于视觉上准备好和首次交互中间忙碌状态时

这是其中一个最复杂的瓶颈,并且没有标准方法来修复这类型的问题。它是独立的,而且取决于应用的特定情况。Chrome 开发者工具有一系列文章帮助我们检测运行时的性能问题。


视觉上完成 / 速度指数

视觉上完成是通过页面截图来计算的,并使用速度指数算法来对那些截图进行像素分析。有时候测量是否视觉上完成也是一件棘手的事情。

如果页面里有会发生变化的图片如轮播图,那么获取正确的视觉上完成结果就可能有点挑战了。

速度指数本身表示视觉上完成结果的中值。速度指数的值越小,性能就越好。

视觉上 100% 完成是一个最终点,决定了用户对页面是否感到满意。这个时间也是用来回答问题 - 用户体验良好吗?


总结

上述并不是所有的 PWM,但是最重要的一部分。上面的指标都增加了一些资料链接,帮助我们更好地提升它们,另外,我还想留出一些关于测量这些类型指标的工具链接:

P.S. 要获得所有这些指标的结果的话,我推荐使用 Lighthouse 或 pwmetrics。Calibre 和 WPT 都可以运行 Lighthouse,并可以通过扩展提供所有这些指标。

如果你想手动测量性能,有一个原生 API,叫 PerformanceObserver,它可以帮助你实现你的测量目标。

规范说明里截取的示例:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24


const observer = new PerformanceObserver(list => {

list

.getEntries()

// Get the values we are interested in

.map(({ name, entryType, startTime, duration }) => {

const obj = {

"Duration": duration,

"Entry Type": entryType,

"Name": name,

"Start Time": startTime,

};

return JSON.stringify(obj, null, 2);

})

// Display them to the console

.forEach(console.log);

// maybe disconnect after processing the events.

observer.disconnect();

});

// retrieve buffered events and subscribe to new events

// for Resource-Timing and User-Timing

observer.observe({

entryTypes: ["resource", "mark", "measure"],

buffered: true

});

感谢所有工作人员,他们在规范说明、文章和工具上做了很出色的工作!






原文发布时间为:2017年10月19日


本文来自合作伙伴掘金,了解相关信息可以关注掘金网站。

时间: 2024-07-30 06:18:09

性能指标都是些什么鬼?的相关文章

android项目文档 ,需要整理准备哪些东西 它应该包括多少个部分,都写些什么呢

问题描述 android项目文档 ,需要整理准备哪些东西 它应该包括多少个部分,都写些什么呢 最近项目越来越大,都出现了65536的问题,由于之前好多人写的,没有系统的整理过,我最近想要写一个相关的东西,该从何入手,都包括哪些内容呢 解决方案 项目说明性文档,一般架构和实现两块.架构说说我准备盖一座什么样的房子,有几个门,几个窗等等,实现写写门是什么材料做的,用到了什么技术,实现了什么功能,如何实现的.类似的梳理过程,卤煮可参考参考. 程序文档自动生成就行了. 解决方案二: 什么相关的东西,网上

axis2生成客户端代码-通过axis2生成的客户端代码都是些什么类,求详细解答

问题描述 通过axis2生成的客户端代码都是些什么类,求详细解答 如图中的类,求解救 解决方案 自动生成的代理类,保证了服务的请求和响应的接口

.net 面试中级都问些什么

问题描述 asp.net工作了2年,整天就是实现业务,数据库的基本操作,真心麻木,感觉这个玩意只要会点基础,在用几天熟悉也就会做了,所以基本工资也就那样,今天接到一个面试电话,叫我过去.都问些什么,帮点忙咯, 解决方案 解决方案二:主要是看公司的大小和公司主要做哪方面..解决方案三:他也没说太多,就是说用asp做,我都不知道要准备些什么东西过去解决方案四:一般一张试卷解决方案五:是asp还是asp.net??解决方案六:说是asp,asp.net应该也会用到的吧,解决方案七:主要是没有面试过,不

老外在TSSJS2005都聊些什么?

js     TheServerSide终于整理好了TSSJS2005的报道 ,顺着可以拖出一长串blog.另外还有所有讲演的简介.      这个搞得像两会似的会议,老外们到底都聊了些什么呢?     老生常谈     首先是Webwork2, Tapestry, JSF, Flex几个个Web Framework一字排开,各做各的宣传.    然后到毫无新意的EJB3.Hibernate与JDO也乘机宣传了一下自己的新版.    当然也少不了SOA和AOP两位常客,SOA还讲了非常多场.  

创业公司团队都需要些什么角色

首先,你要明白一个创业团队的核心就是团队leader.一般来讲投资界对于初创团队最看重的就是Leader人怎么样,而不是项目怎么样,idea怎么样.那么一个优秀的leader应该是什么样子的呢?无论是盖茨还是乔帮主,尽管其个人气质(一个是工程师气质,一个是产品经理气质),或是工作方式(盖茨习惯亲自上阵撸代码,乔帮主都是指挥别人怎么做)都有极大地不同.但总的来说,其根本的一些品质,肯定是必须的. 1.正当而不泛滥的责任心.权力和责任对等,既然是leader,权力自不必说.但是否能在关键时刻挺身而出

BlackHat专题 | 带你看 BlackHat 现场,全球顶级黑客聚会都做些神马?

       美国时间2016年8月3日,全球顶级黑客一年一度的聚会--BlackHat USA--又开始了. 上万名黑客黑压压地集结在"罪恶之城"拉斯维加斯的曼德雷湾礼堂,成群结队,如候鸟南归.这种场景听起来有一种要毁灭世界的阵势.不过请放心,这些来自世界各地的白帽子黑客大多样貌慈祥,而且看上去温顺和善. 他们前来此地,布道或朝圣.黑客精神是他们共同的信仰.相比毁灭世界,他们对拯救世界更有兴趣. 如此重磅的聚会,雷锋网怎么会错过呢?雷锋网(公众号:雷锋网)编辑搭乘最早的一班长途汽车,

Facebook发布财报在即 看看市场都关注些啥

1月27日消息,据外电报道,随着Facebook早已成为全球社交媒体市场的龙头,在本周该公司发布2015年第四季度财报时,华尔街关注的重点将是该公司旗下的各项业务能够继续保持超高的增长速度. 与许多的互联网公司一样,在本周三发布财报时,Facebook同名平台的月活跃访问用户数量将成为投资人和市场分析师关注的重点数据之一.分析师预计,Facebook的月活跃用户增长情况将会同第三季度类似.瑞穗证券分析师尼尔·多斯(Neil Doshi)说,"我敢说Facebook第四季度的业绩又将会超出市场预期

Google公司都是些什么牛人?

1 Vinton Cerf :号称互联网之父,TCIP/IP协议和互联网架构的合作设计者.他05年10月3日开始正式为Google工作,职位为"首席互联网传布官". 2 Joshua Bloch :号称java教父,<Effective Java><JAVA PUZZLE>的作者,JSR175标准的leader,J2SE 1.5的主要开发人员之一. 3 Guido Van Rossum: Python之父.Google把Python用的炉火纯青,有了Python

java-Java反射getDeclaredFields()方法返回奇怪的值

问题描述 Java反射getDeclaredFields()方法返回奇怪的值 问题是这样的,项目中,定义了一个java类:在初始化方法中public static void initSysConfig(){ try{ Field fields[] = SYS_CONFIG.getClass().getDeclaredFields(); for(int j = 0;j<fields.length;j++){ System.out.println(fields[j]); } --但最后,调用一个im