译者按:dynaTrace是迄今为止在IE平台上出现的最好的javascript性能分析工具,没有之一。他是不折不扣的王者。不过本人英文水平很烂,对于长篇英文阅读起来相当吃力,为了后来的英文不好的同学读起来不那么不那么难受,我就花点时间翻译出来吧,作为前端工程师,应该掌握这样优秀的工具,闲言碎语不多说,下面文章说端详。
dynaTrace Ajax版学习指南,现可公开下载
dynaTrace Ajax内测版发布已有两周了。它给你的第一印象是什么。那段时间内我们收到的所有反馈意见(例如来自Steve Souders的意见,以及来自所有其他联系形式和在线论坛的意见)使这款工具从它的早期版本过渡到它的第一个“官方”发布版成为可能。
在这篇博客里,我将就dynaTrace Labs为什么要构建Ajax版工具展开讨论,它解决了什么问题,以及如何在一个关于Google Maps的例子中使用它。
为什么要开发dynaTrace Ajax版——为什么免费?
在dynaTrace网站,我们看到我们的客户跟业界一样,将以浏览器和运行时(Javascript、DOM)为基础的Web应用作为其应用平台。那些新兴的框架,像jQuery、GWT、YUI、Dojo等,让构建web 2.0应用越显轻松——但是,也越来越难以确认应用中的问题到底是功能性的,还是与性能相关的。
即便是在企业环境中,排名第一的仍然是IE浏览器。IE的诊断工具在涉及问题分析时,常会给开发和测试人员带来痛苦。在Web2.0/Ajax应用中所面对的挑战不仅是要了解网络交互(有多少资源以及什么时候载入),而且要了解这些交互是如何影响性能的。该问题所涉及的领域已经延伸到JavaScript、XmlHttpRequests、DOM操作、框架、布局和渲染。dynaTrace Ajax版的来临即可解决这类问题,以帮助用户了解是什么原因导致现代Ajax应用中出现性能和功能问题。
那么,为什么免费呢?免费是因为我们想帮助开发和测试人员通过使用这款工具来解决web 2.0带来的各种挑战。我们也希望推广dynaTrace APM解决方案理念,即结合Ajax版所带来的端到端的浏览器到服务器的以事务为中心的应用性能管理解决方案。在这里可以继续阅读完整的关于软件免费的原因说明。
动手分析Google Maps——从安装到分析的学习指南
我已经导出了学习这篇博文所需要的dynaTrace Ajax的session文件,点击这里免费下载,然后用它跟着我对我收集的这些数据进行逐步分析。如果你已经安装了dynaTrace Ajax版软件,就解压缩这个zip文件,点击工具栏中的导入按钮导入session文件(.dtas),然后跳过前三步。
第一步:下载并安装dynaTrace Ajax版
最一开始就是——对了,下载并安装。
打开浏览器,进入dynaTrace Ajax版网站,点击Download按钮下载最新版本。你必须先注册一个账户,这个账户不仅可以让你下载该工具,还能给你在社区网站开通权限,在那里你可以获得资讯、咨询问题,甚至为软件期望的功能提供建议。
第二步:启动并查看dynaTrace Ajax版
点击开始->所有程序->dynaTrace->dynaTrace AJAX Edition启动dynaTrace。客户端将出现Cockpit面板(译者注:左侧)及欢迎界面(译者注:右侧)。在我们开始追踪Google Maps之前,让我们先来浏览一下一些数据收集选项:
开始分析之前运行配置和预置功能
dynaTrace使用被称为运行配置的方式,使你可以直接浏览你要分析的网站而不用每次都要在你的浏览器里键入url。你可以通过左上角工具栏中的下拉菜单来管理你的运行配置(添加新的、修改或者删除现有的配置)。选择Manage Run Configuration来预置http://www.google.com网站,参看下面的截图:
管理网址
如截图所示,也可以让dynaTrace在开始追踪网站之前情空浏览器缓存。这一功能在你要测试你的网站在没有缓存的情况下运行的怎么样时非常有用。另外一件重要的事是通过点击工具栏最右侧的按钮可以启动Preference(预置)对话框。
在Preference对话框中启用捕捉参数
你可以在这里指定多个不同的配置。值得注意的是那个开启/关闭捕捉JavaScript和DOM方法调用的选项,以及开启/关闭Javascript一般追踪的选项。在下面的练习里,请勾选“Capture arguments”以及“Capture full JavaScript call trace”选项。
第三步:开始分析Google Maps
让我们开始吧。你既可以通过选择工具栏中的Google运行配置,或者点击欢迎界面的“Start Tracing”,再或者直接按F4快捷键来启动软件。接下来,dynaTrace将启动一个IE的新窗口。如果你选择了清除浏览器缓存,dynaTrace将在打开http://www.google.com之前开始执行这个操作(这可能会占用几秒钟的时间)。你可以通过浏览器程序图标是否改变来判断dynaTrace此时是否正在追踪页面执行过程——你会在浏览器窗口的左上角看到一个小dynaTrace图标,以及一个dynaTrace工具栏显示“已连接”:
通过dynaTrace启动浏览器
如果你没有看到这种情况出现,请到论坛的General Usage Question(译者注:常见使用问题)版块查询故障排除技巧,或者通过在线反馈或论坛联系我们。接下来,请跟我完成这些步骤:
- 在搜索框里一字一顿的键入“dynaTrace”——每次输入,你都会看到弹出Google的搜索建议框
搜索“dynaTrace”
- 完成输入后,按回车键或者点击Google Search按钮;
- 当出现搜索结果后,点击页面顶部的“Maps”链接,切换到Google Maps;
- 你将看到很多关于dynaTrace地点的搜索结果。点击在“95 Hayden Avenue,Lexington,MA”的“dynaTrace Software”,让地图显示这个地址。
用Google Maps搜索dynaTrace
这是我的测试结果。在我们关闭浏览器之前,你可以快速看一下dynaTrace软件界面,你会看到在“Bowsers”下面有一个节点,那就是当前正在从IE中收集的信息。我们可以在运行浏览器的同时分析这些数据,也可以关闭浏览器,然后再分析我们捕获的。让我们动手分析吧——关闭浏览器,切换回dynaTrace AJAX软件界面。
第四步:Summary视图(摘要视图)——高级分析
浏览器中记录的事件被自动存储在一个session(译者注:会话)中,我们可以在浏览器关闭的情况下分析这些被捕获的浏览器活动记录。在左侧cockpit面板中,你可以双击session,或者展开这个session节点,双击Summary节点。这两种操作都会启动Summary视图,它为我们呈现session记录中所有活动的高级分析结果:
Summary视图显示每个访问过的URL的高级分析结果
Summary视图显示了session记录中所有访问过的URL链接的信息。点击顶部表格中某个具体的url下方就会更新图表和时间线来显示所选链接的数据。在这个视图中我们可以得到以下信息:
- 载入页面所耗时间:Page Load Time[ms](页面载入时间[毫秒])栏显示从页面开始载入到浏览器派发onload事件所经历的时间;
- 网络请求花了多长时间:下方NetWork饼图从DNS解析、网络连接、服务器响应以及网络传输方面详细分解网络请求过程,由于网络内容在这段时间里是并行下载的,所以NetWork[ms]栏则显示的是所有网络请求时间的总和;
- 下载了多少以及什么类型的资源文件,对比有多少资源是从浏览器缓存读取的(Resource条形图);
- 通过JavaScript触发器(脚本载入、载入完毕、鼠标、键盘等事件)和JavaScript API或库执行的所有JavaScript函数一共耗时多长时间;
- 渲染页面所占时间。浏览器必须计算布局并渲染页面显示。浏览器重新计算布局和重绘的时间取决于你的HTML、样式表以及动态DOM操作。Rendering[ms]栏显示了页面在渲染工作上实际消耗的时间。
- 屏幕下方的时间轴图显示精确的页面生命周期:该图反映了页面进程中网络资源下载、JavaScript执行、页面发生渲染的时间,CPU占用情况,以及发生了哪些事件。例如:onLoad事件、鼠标或键盘交互、XmlHttpRequests等。
在我们的例子中,以下内容引起了我的注意:
- maps.google.com页面的页面载入时间为6.5秒:这是页面在派发onload事件之前浏览器初始化html和所有引用的对象所消耗的时间;
- 这页面的网络时间耗时12秒。当我观察该页面的Network饼图时,我发现50%多的时间消耗在传输内容(这也可能意味着我的网速慢)上,42%的时间花在服务器响应上(指过了多长时间服务器开始响应),以及8%的时间消耗在与服务器建立物理连接上。
- 总耗时3.6秒的JavaScript也是重要角色。JavaScript trigger饼图显示时间的具体消耗情况:载入script耗时2.1秒,onload事件派发耗时1.3秒,剩下的由鼠标点击事件处理占用。
- 时间轴还显示页面发出了2个XmlHttpRequest请求。它由一个小图标标注在event行中请求发生的时间点上。下一节将进行更详细的讨论。
第五步:Timeline视图(时间轴视图)——近距离观察页面生命周期事件
时间轴视图可以通过双击Cockpit面板中的Timeline节点打开,或者在Summary视图中通过在某个URL上点击右键,选择“Drill Down-TimeLine”打开。我们用这种方式打开maps.google.com页面:
查看某个url的Timeline
点击“drill down(译者注:详细)”菜单将打开所选页面的Timeline视图,通过工具栏和右键菜单,你可以打开更多选项,比如内容类型和JavaScript触发器的颜色值,或者显示更多事件,比如鼠标移动,点击和键盘事件。下面的截图显示时间轴开启更多选项的效果:
针对选定页面的Timeline显示网络、JavaScript、渲染、CPU和事件
我们可以在此视图下做如下观测:
- 网络请求并行下载来自6个不同域的内容;
- 到浏览器派发onload事件大约需要6.5秒(图中由IE图标标识);
- 从maps.gstatic.com下载main.js耗时2.41秒(鼠标悬停在这段上可以看到详细信息);
- main.js下载完成后,可以看到脚本实际执行耗时1.1秒,并触发两个JavaScript文件的下载(1秒)和另外2个JavaScript的执行(2秒);
- CPU占用率显示JavaScript执行占用的浏览器CPU时间;
- Event轴显示了鼠标点击事件,XmlHttpRequest事件和onUnload事件。
我们缩大鼠标第一次点击到产生XmlHttpRequest请求的时段。在我的例子中,这个时间片是从11秒到12秒。通过在开始处点击鼠标左键拖拽到结束位置来执行放大操作。当你松开鼠标拖拽的,视图将放大到下面截图中显示的时间片上:
放大时间轴以显示事件详细信息
时间轴上显示了点击事件,一个XmlHttpRequest事件,其后紧随一个onError事件,再后一点还有一个XmlHttpRequest(XHR)事件。鼠标悬停在事件上将显示实际派发事件的DOM元素。鼠标悬停在JavaScript上将显示脚本执行事件处理的时间,悬停在network请求上将显示下载了哪些资源。我们也能看到浏览器执行了哪些类型的渲染。我们发现第一次鼠标点击事件处理函数触发新内容的加载——包括一个来自maps.gstatic.com的JavaScript文件。执行这个JavaScript文件——一旦它被加载以后——触发了一个XHR请求。我们还能看到一个onError时间处理函数被触发并且运行了240毫秒。
第六步:PurePath视图(路径视图)——JavaScript、DOM和Ajax问题的详细说明
从Timeline视图(和从其他视图一样)我们可以更进一步进入每个动作去观察事件触发执行了哪些JavaScript函数和哪些JavaScript函数发出了XHR请求。在时间轴上点右键选择“Drill Down to Timeframe”(进入详细时间片)将来到PurePath视图,并显示当前所放大的时间片上所有的活动——如下图:
进入指定时间片的PurePath视图
在界面上方,我们可以看到所选时间片中浏览器的所有活动,包括由script标签或事件响应触发的JavaScript的执行情况。也包括网络请求和渲染次数。Stats(译者注:统计)栏显示该行执行的JavaScript触发的是计时器还是Ajax请求。那些占总体响应时间较多的活动会被彩色高亮显示。
在PurePath列表中选择一个活动,PurePath或JavaScript追踪树将更新显示当前所选活动的信息。PurePath树显示了JavaScript代码执行过程,包括每个方法执行的时间和调用的参数以及返回值(我们在第二步中开启了参数捕获选项)。代码跟踪也追踪计时器调用,并把这些调用当做树的一部分。我们不仅能看到JavaScript方法,也能看到DOM访问和AJAX请求。
我们后退一步,回到前一个Timeline视图。我对Ajax请求比较感兴趣。双击Event行中的图标打开一个新的PurePath视图,软件会在JavaScript跟踪中找出实际执行这个XmlHttpRequest的位置:
进入PurePath视图分析XmlHttpRequest细节
在界面上方我们能看到的执行这段代码的JavaScript文件——请看Details栏。在树中我们能看到发出这个XHR请求的整个JavaScript执行过程,包括方法调用次数和调用参数。duration栏显示JavaScript执行共耗时1127毫秒。这个时间包含了XHR返回的时间和等待JavaScript计时器的时间。打开这个网络请求的详细信息(译者注:在PurePath树中定位的Network Request上点右键,选择“Details”),将显示Http请求和响应头、请求的精确时间,包括连接、等待、服务器响应和网络传输时间,还有从服务器返回的实际内容(译者注:在Details面板底部有个切换标签Details/Response Content可以查看)。
XmlHttpRequest请求详细信息
这个请求有趣的地方是服务器花了372毫秒返回了一个空的json对象。从这我们可以继续分析,看一下是什么实际完成这个Ajax响应的。回到PurePath树,我们“drill down”到onreadystatechange事件处理函数(译者注:在NetWork Request下有三个“JavaScript Execution”,是onreadystatechange触发的三次函数调用,展开第三个可以看到这里的readyState为4,开始调用响应函数,一个匿名函数anonymous即是onreadystatechange的事件处理函数)。下面的截图显示了这个处理函数,右下方显示这个函数的代码:
分析XHR请求的JavaScript处理函数
这里最有意思的是左下方Contributor栏显示了当前所选子树的所有JavaScript活动。最上面一行显示使用了一个动态script标签,标签的内容被写入一段脚本来让浏览器动态加载了一个JavaScript文件。双击Contributor栏中的这条数据定位到PurePath树中的位置(译者注:可能要拖动横向滚动条、拉宽PurePath树的显示宽度才能看到,这个位置折叠的层级很深):
动态创建一个Script标签并插入到DOM中
在这里我观察到:
- 一个计时器用了大概740毫秒来触发计时器处理函数——注意截图中第三行的setTimeout方法调用;
- 创建了一个动态Script标签,并把它添加到head中,指示浏览器下载这个Script文件。(译者注:通过观察我觉得“<标签名>”即指代一个[标签名]类型的DOM对象,.setAttrbute、.appendChild即为调用该DOM对象的DOM方法。)
PurePath视图提供了多种分析方法。你可以通过直接键入(译者注:几乎在任何地方都可以执行键入查找操作,只要点击一下要查找信息的控件,使其获得焦点,然后按键即可)你要查找的内容来筛选或查找你需要的数据项。通过右键菜单或工具栏按钮添加过滤规则可以让软件只显示特定信息。
第七步:Network视图(网络视图)——分析“对话”
Network视图显示了发生在浏览器或各自页面中的所有网络请求。通过双击左侧Cockpit面板中的Network节点,或从Summary视图中某个URL上右击选择“Drill Down – Network”进入到Network视图。在我的例子中,我回到Summary视图,然后“Drill Down”进入maps.google.com的Network视图:
Network视图高亮标记出超慢的请求以及连接等待时间
这个视图下会用颜色标记每个请求,并且用红色高亮标记出耗时最长的下载请求。默认情况下,这个视图是按“Time Chart”栏排序的,Time Chart栏显示浏览器发送的请求队列。
从每个请求上我们可以到的资源是否来自浏览器缓存(Cached栏),请求类型(Network或Ajax),HTTP状态,Mime类型,大小,在DNS、网络连接、服务器响应、网络传输和等待上消耗的时间。界面底部显示了HTTP请求和响应头以及返回的实际内容。这个页面中有趣的地方是从mt0.google.com和mt1.google.com取回数据时的等待时间。每个浏览器针对每个域名都有一个连接数上限。
在我的例子中(WinXP系统,IE7浏览器)是每个域名最多保持两个连接数。20个PNG图片从两个域中加载过来。由于连接数限制,使得每个域名只能并行下载两个图片。其他图片便是不得不等待一个可用的连接数。这就解释了为什么这些图片和不断增加的等待时间呈“瀑布”型。我们可能不希望在不同浏览器和不同连接数情况下出现像这里这样的效果。解决这个问题是使用域名碎片(Domain Sharding)或者CSS拼图(CSS Sprite)。
和其他视图一样,从这里可以进入PurePath。我们定位到页面上第二个Ajax请求。对Kind列进行排序,然后选择一个响应类型为text/xml的请求。点击鼠标右键,选择Drill Down->PurePath,进入PurePath视图,软件将自动定位到JavaScript追踪中发出这个XHR请求的JavaScript函数上。
进入PurePath视图
第八步:Hotspot视图(热点视图)——哪些地方降低了性能
最后一个有趣的视图就是Hotspot视图。通过Cockpit面板打开,或者Summary视图打开来分析一个具体URL。本例中我们从Cockpit中打开HotSpot视图来分析我访问过的页面中所有的JavaScript、DOM和渲染动作。
Hotspot视图显示了有问题的活动,包括活动前后的追踪
上方的表格以聚合的方式显示所有JavaScript、DOM和渲染动作。我们可以看到130次的Drawing动作,946次Reflow动作以及在一个div上调用了一个匿名函数1293次。这个列表是按总的执行时间排序的,性能越高排序越靠上。
双击这些中的一个,将显示它执行前后的追踪结果。Back Traces表显示了谁来调用这些动作,Forward Traces表显示的是这个动作又触发了哪些动作。界面底部显示了在Back Traces树或Forward Traces树中选中的JavaScript的源码。我双击了那个调用946次的reflow动作。reflow动作在浏览器下载图片或者其他对象或者应用样式时触发。不过,它也在访问某些DOM属性或调用某些DOM方法时触发。在Back Traces中显示读取offset或height属性会引起浏览器渲染引擎的一个reflow动作。回溯可以看到哪个JavaScript方法访问了DOM。从界面上方的Contributor表可以进入PurePath视图。打开PurePath将展开包含当前选中的方法的PurePath树——类似前面我们展开XHR请求的PurePath树。
第九步:自动化数据集
除了用dynaTrace手动收集数据,也可以用脚本工具代替人工方式驱动浏览器自动收集数据。当你用像Selenium、Watir、WebAii这样的工具运行测试脚本是,dynaTrace可以自动从每个浏览器session中收集性能信息。这里有篇博文《5步实现性能自动分析》,教你如何用Watir配合dynaTrace自动分析。
第十步:与你的同事分享数据
收集信息并制成离线版分析数据是dynaTrace的功能之一,上面你已经领略到了。如果你在别人的代码中发现了问题,或者你想跟你的同事分享你的发现,你需要一种简单的方式共享你收集到的数据。这可以通过把你的session导出为session文件实现。在Cockpit面板中的右键菜单或者工具条里的导出按钮能完成这一工作。导入文件的操作与此类似。
导入导出dynaTrace session文件
总结和反馈
dynaTrace AJAX版是一款非常棒的针对IE6、7、8的分析和测试工具。社区已大力推广第一个官方版软件,它兼容前一个测试版。我们鼓励大家积极参与这款软件的推进工作,通过社区网站或软件工具栏的报告功能报告使用问题。
工具栏中的反馈、分享和报告问题按钮
工具栏里有三个按钮可以让你与好友分享这款软件、给我们反馈信息或者报告使用问题。目前我们的许多客户使用AJAX版来确定和解决他们的浏览器前端组件问题,至今我们已经从他们那里得到了一些很好的意见。这些用户也使用了集成dynaTrace无缝APM解决方案,为他们提供从浏览器到后台的端到端全方位分析。感谢你跟着我一起完成了这个有点长的学习指南。欢迎给这篇博客留言,说说你在dynaTrace或者其他工具使用上的经验。