从用户体验出发的性能指标分析-DOM Ready

如何在持续升级的项目中保持项目的高性能?如何更加准确的定位和解决性能问题?实际上,WPO的最主要目的是改善用户体验,而用户体验的好坏则可以根据几个核心性能指标来衡量。从用户体验出发的几个核心时间指标包括:Start Render、DOM Ready、Page Load、TTI。不同的性能指标对用户体验的影响是不同的,而指标本身受哪些因素的影响也是不同的。优化某个指标又该具体采用什么样的方式?接下来将一一介绍,本文集中介绍DOM Ready。

 

定义

    DOM Ready,指的是页面解析完成的时间,在高级浏览器里有对应的DOM事件 – DOMContentLoaded,Firefox官方的解析如下:

Fired at the page’s Document object when parsing of the document is finished. By the time this event fires, the page’s DOM is ready, but the referenced stylesheets, images, and subframes may not be done loading; use the "load" event to detect a fully-loaded page.

    即该事件在文档解析完成时会触发。那么文档解析到底包括哪些操作呢?虽然暂不能给出一个完全的答案,但文档的解析至少应该包括以下操作:HTML文档分析以及DOM树的创建、外链脚本的加载、外链脚本的执行以及内联脚本的执行,但是不包括图片、iframe等其它资源的加载。正因为如此,该事件触发的时机一般比window.onload要早,而且是在所有DOM元素都可以操作之时。

    目前,HTML5也对该事件进行了规范,IE9也开始支持该事件了。

用户体验

    Start Render指标直接决定着用户对页面速度的体验,与此不同,DOM Ready指标并不直接影响感官体验,往往影响的是交互功能何时可用。为何影响的是交互呢?由于DOMContentLoaded事件触发时是所有DOM节点可以进行操作的时候,比如添加事件、增删改节点等,因此用Javascript实现的一些交互功能往往会在DOMContentLoaded事件中去初始化,也只有在DOMContentLoaded事件触发后这项功能才可用。

    所以说DOM Ready指标影响的是交互功能的最早可用时间,DOM Ready时间如果过长的话,用户会发现页面已经出来了,但是很多功能却是不可用的,也许点击某个链接会跳到页面顶部。因此,DOM Ready时间也是越短越好,这样交互功能才能尽早可用。

影响因素

    先来看看一个粗略的时间组成公式:

    Time To Dom Ready = TTSR + TTDC + TTST

其中:

    TTSR(Time To Start Render):浏览器开始渲染的时间

    TTDC(Time To Dom Created):DOM树创建所耗时间

    TTST(Time To Script):BODY中所有脚本加载和执行的时间

    通过以上公式可以看到Start Render主要受以下因素影响(开发人员可控):

    (1) DOM结构的复杂程度

    (2) BODY中脚本使用情况

    通过对一些实际监控数据的分析得出,在一个通过正常方式加载脚本的页面中,脚本的加载和执行时间往往能占DOM Ready时间的50%左右,由此可见脚本的使用对DOM Ready指标的影响如何的显著!因此,对DOM Ready指标的优化也应该着重从脚本的使用入手。

    (3) Start Render指标的影响因素

监控方式

    监控方式目前各个框架都有自己的实现方案,大致的情况是在“现代”浏览器中通过注册document的DOMContentLoaded事件来监控,而像类似IE9以下各个不支持该事件的浏览器则使用模拟的手段来处理。关于主流框架中的实现方案可以参考《主流框架中DOMContentLoaded事件的实现》

优化方法

    从DOM Ready时间的影响因素着手分析:

    (1) Start Render指标相关的优化方法

        (a) 减少服务器响应时间

        (b) 减小HTML文档体积

        (c) 减少Head中资源使用(脚本个数、执行时间)

    (2) 减少BODY中脚本的使用(重点)

    脚本的加载和执行时间是影响DOM Ready指标的最关键因素。外链脚本在加载和执行的过程中会阻塞页面的解析,内联脚本在执行的过程中也会阻塞页面的解析,因此脚本加载和执行的时间越长则DOM Ready的时间就越长。

    优化脚本应该从加载和执行两方面考虑:

        (a) 加载:动态加载脚本时将不会阻塞文档的解析,因此所有外链脚本都应该尽可能的通过动态加载的方式来加载,关于动态加载相关的技术可以参考《Loading Scripts Without Blocking》。目前最为常用的方案是文中提到的"Script DOM Element"。

        (b) 执行:虽然动态加载的脚本在加载过程中并不会阻塞文档的解析,但是假如在DOM Ready前加载完成,则脚本在执行的过程中仍然会阻塞文档的解析,包括渲染。此外,如果是内联脚本,如果执行时间长依然会阻塞文档解析,这种情况可以考虑将内联脚本放在DOM Ready后执行或者通过异步方式来执行。而对于外链脚本的执行问题目前大多数方案都是让外链脚本先加载但是尽可能迟的去执行,例如DOM Ready后执行亦或是按需执行。对于外链脚本的延迟执行,也有不少人给出了具体的解决方案,例如Steve Souders的ControlJS就是将各种技术结合起来提供了一整套的解决方案。其主要思路是在页面解析进行时,通过Image或者Object预加载脚本,这时候加载的内容是被浏览器缓存的,但是因为不是脚本因此不会立即执行,但需要执行时则创建script标签重新请求,由于浏览器有缓存因而会立即执行。

    (3) 减少或延迟加载BODY中脚本之外的资源

    虽然说DOM Ready不会受图片等资源加载的影响,但由于如果图片数量过多而且较大时会较长时间的占用HTTP连接数,这会导致这些资源之后的脚本资源加载受阻,而按传统方式加载的脚本加载得越晚则意味着DOM Ready时间也会越靠后,因此如果图片数过多或者图片过大的话可以考虑使用延迟加载或者对图片本身进行优化,减少图片对连接数的占用。

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

2 Comments »

 
 

Leave a Reply

您必须 登录 才能发表评论。