用户体验评测工具—jiffy原理及思想

作者:Bill Scott    译者:iammutex

原文链接:http://hi.baidu.com/iammutex/blog/item/e897e91f0c91a2174134170c.html

英文链接:http://looksgoodworkswell.blogspot.com/2008/06/measuring-user-experience-performance.html

.

用户体验的评测

我在Netflix的一个项目目前正忙于改善客户端用户体验。经常看我BLOG的朋友应该知道,我是一个对完美的用户体验执着追求的人。虽然通常对用户体验的考虑并没有包括性能这一步,但是我们常常可以看到一种情况,就是完美的设计毁在了迟顿的实现上面,在一个页面前等老半天才能让用户能够进行交互的操作,这真是一点都不及时。

记录“从点击到完成”—-整个周期的用户体验

用户体验集中的表现在这样一段时间上,即从用户请求一个页面到完全地得到这个完整的页面(已经可以进行交互)这样一段时间。很多网站对特定的一些性能也有自己的一些性能跟踪的手法。通常后端用来记录后端的服务时间(译者:页面给出去了就不管了)。但是基本上的网站都没能真正衡量到,从用户点击链接到完整得到返回这段时间到底有多长。

在Netflix,为了记录上面说到的信息,我发起的第一件事情就是建成一个完整的请求周期跟踪系统。Kim Trott(我团队的一员)承担了这个任务,具体去实施它,并最终将它变成现实。

完整请求跟踪系统具体是要做:

  • 获得开始请求页面的时间
  • 获得我们感兴趣的各种中间点的时间
  • 获得完整得到请求内容的时间
  • 记录上面的结果

得到开始请求页面的时间(“从点击开始”)

要得到完整请求周期的时长,我们必须及时地得到用户提出请求的时间。

在Neflix 我们用下面的一些技术:Java,JSP,Struts2,Tiles2,HTML,CSS 以及 Javascript。我们使用Java sevlets来完成最通常的HTTP请求/回复–这样的一个完整请求周期(最后通过JSP返回页面)。

1ad374c62ed499fed000604d

Unload事件

从逻辑上来说,衡量请求开始(从点击开始)的最精确的时间点是在上一个页面中的(如上图的A点)。最直接的方法是在上一个页面的unload事件发生时(或者说马上要发生的时候)做一个时间记录。有很多方法可以做这样的工作,而最通常的做法是将时间信息(比如可能包括请求的URL,用户浏览器类型,时间等)写入到cookie中。

然而,这方法有一个缺点。比如用户是从别的站点跳到你的主页来的(比如从google搜索进来的)。那因为上一个页面不是我们可以控制的,unload事件也不是发生在我们的网站上,那我们就根本得不到这个“开始时间”了。所以我们需要一个稳定的“开始时间”。(译者:显然,这种方法在自己网站的各页面内跳转是没有问题的,但上面说的就记录不了,因此说不稳定)。

服务器响应时间

我们可以记录服务器响应时间,从而得到和刚才不一样的一个开始时间,我们可以在服务器响应请求前尽可能靠近请求的时间点上设置一个时间记录器(如上图的B 点)。这样就保证了我们总能得到一个开始时间(译者:而不是上面不稳定的时间)。虽然这样做确实是将从请求到生成返回内容那段时间给忽略了,不过他终究还是得到了这个周期中很重要的一部分—从返回值形成这一时间开始的部分。

有很多方法可以得到这个数据,因此他可以通过请求传递,并最终被记录下来。你可以写成服务器端的cookie。你可以后面json对象内嵌在页面中。你甚至可以通过URL的参数把它传递过来(尽管因为这样那样的原因我们并不会这样做)。重要的是你需要有一种方法可以把这个数据保存起来,直到它被记录下来。

注意,这里获得的这个绝对时间是服务器时间而不是客户端时间。也并没有任何机制可以保证这两个时间能够同步,这个问题我们后面会再讨论。

获得在下面的过程中我们感兴趣的时间点

在得到了开始时间之后,还有几个标准的时间我们需要捕获。

be366735707062195ab5f54f

有两个我们感兴趣的时间点是在服务器端得到的。

  • 当我们开始生成HTML页的时间(C)
  • 当我们完成了HTML页的生成的时间(E)

还有两个我们感兴趣的时间点是在客户端得到的。

  • 当页面开始渲染的时间 (D)
  • 当页面渲染完毕的时间 (F)

C和E负责的是HTML文档的生成,D和F是负责页面渲染。 在D操作中,我们是通过一段小脚本,在标签被显示完成后立刻记录一下Data().getTimer(),将结果生成一个Javascript对象保存在页面中。

在F操作中,我们也是通过一段小脚本,在标签显示完成后记录一下Data().getTimer(),将结果生成一个Javascript对象保存在页面中。

当页面开始了对HEAD的渲染,马上就会执行D这一步并且保存当前的时间戳。而当BODY渲染完成时又会马上执行F这一步并且保存此时的时间戳。

记录终止时间(“完成”)

当F完成时,可以说这个页面就完全渲染完了。与此同时,浏览器也在做加载CSS,Javascript,请求图片这些工作。但是页面还不支持用户与之交互(一般来说),因为交互操作要等到onload事件完成时才可以进行(如下图G点)。
5f36895d41d43261faf2c048

我们将我们的时间采集器放在onload事件的最后来执行。

将获得的时间保存下来

下面有一个图描述了我们所有捕捉到的时间点及我们测量的时间段。
f23e3d0f3c1eb6e87acbe149
这五个时间段是:

  • 从客户端请求开始到最终的时间 (G-A) 。就是我们所谓的整个周期。所有这些时间包括发出请求,得到返回值,再对返回值做页面渲染。 这个只有在上一个页面也是我们Netflix的页面时才有效。这个值并不具有普遍适用性。
  • 服务器响应用时 (E-B) 。 生成这样一个返回页面我们总共花了多长时间。
  • 客户端渲染用时 (G-D). 客户端花了多长时间去完全渲染这个页面 (包括得到服务器端的返回)。由于我们的返回信息是以流式传送的,因此没有方法区分有多少渲染时间用于从服务器得到请求。实际上浏览器在一接收到返回开始就开始做渲染的工作了(译者:也就是说其实后继数据还在传说当中,前面的数据就渲染成我们可以看到的页面了)。
  • 服务器时间+客户端时间 (C-B) + (G-D).生成页面所用的时间;所有用来生成响应的时间加上客户端渲染的时间。这是一个主要的衡量指标,他包含的是一个稳定的开始时间,一个我们总能够得到的时间。 这个时间是客户端渲染的时间 (G-D) 加上服务器响应的时间(C-B).通过分别对客户端时间和服务器时间做差我们可以把两个差值加起来,做为总时间(尽管服务器时钟和客户端时钟不同)。这里有一个要警告的事情是,在得到HEAD标签的时间C和开始渲染HEAD标签的时间D之间,有一个间隔。但是在实践中我们发现这个时间间隔非常小,因此我们一直采用这个简单的方法来做计算。
  • 在Body渲染完后花的时间 (G-F). 这个时间给我们一个大概的印象,就是从body标签渲染完到页面真的完全加载完之间,还有多长时间。

这样一来,我们就可以收集这五个结果(可以通过目前存在的客户端服务器可以交流的cookie,或者其它方法)。可以通过Ajax请求,通过 beacons,一个不要求返回的HTTP请求或者其它的机制。后端获得这些结果并且把他们存入数据库供以后的分析所用。

性能分析的好处

我们可以在不做任何衡量的情况下,按照yslow的性能优化建议的来做性能优化。也很可能我们所做的都会有好处。但是通过上面这样一套完整的性能测试,我们可以底气十足的指出,我们网站中的性能增强、我们网站的处观、甚至是我们为了改善性能而做的一些优化,是否影响到我们的性能了。

最近我们在页面中放置了一些星级评选的侧边栏。尽管这样做使得HTTP请求数减少了一半(这倒是这好事),但是他确实是降低了性能。拥有实时的性能数据,让我们可以轻易地把寻找低下性能罪魁祸首的范围大大缩小。这样一个反馈系统对性能优化来说是一个非常好的工具。通过我们巨大的用户基础,大点的日页面点击量,我们可以真正得到可靠的用户体验的度量,而这个度量,正是我们的用户的真正体验的反馈。顺便说一下,对结果取中位数是一个概括结果的最好方法,因为他很好地照顾了那些个别的例子(普遍认为,不同的带宽,不同的浏览器性能,都会影响测量)

相关阅读

Tags: ,

我来说两句