The dynaTrace AJAX Edition has been out there as an Alpha for a couple of weeks. It gave you the first impression what was to come. All the feedback we have received (like that from Steve Souders, and all that has come in via the contact form and the online forum) in that time made it possible to improve the tool from its early versions to its first "official" release version.
In this article I'll discuss why dynaTrace Labs built the AJAX Edition, which problems it solves and how to use it in an example with Google maps.
At dynaTrace, we see the paradigm shift of web applications with our clients as well as in the industry where the browsers and their runtimes (JavaScript, DOM) become application platforms. The rise of frameworks like jQuery, GWT, YUI, DoJo, ... make it easier to build Web 2.0 applications - but it has become harder to identify problems in these applications whether those problems are functional or performance related.
The number one browser is still Internet Explorer - even more so in enterprise environments. Diagnostics tools for IE are rare leaving developers and testers with lots of pain when it comes to problem analysis. The challenges in Web 2.0/AJAX Applications are not only to understand network interactions (how many and when resources get downloaded), but also how this effects performance. The problem field extends to JavaScript, XmlHttpRequests, DOM Manipulations, Frameworks, Layouting and Rendering. dynaTrace AJAX Edition has been built to address all these issues to help understand what is causing performance- and functional-related problems in modern AJAX Applications.
Now - why is it free? It's free because we want to help developers to testers with the challenges that Web 2.0 brings with it. We also want to bring awareness of the dynaTrace APM Solution which in combination with the AJAX Edition brings end-to-end, browser to server transaction-centric Application Performance Management. Read the full explanation on Why are we giving away free software?
I've exported the dynaTrace AJAX Session file that I used for this blog entry. Feel free to download it and use it to follow my individual analysis steps based on the data that I've collected. Extract the zip file and import this session file (.dtas) via the Import button in the Toolbar and skip the first 3 steps.
In the beginning there was - correct - downloading and installation
Open your browser and go to dynaTrace AJAX Edition Web Site and click on Download to download the latest version. You have to register an account which not only allows you to download the tool but also gives you access to the community pages where you can find additional useful information, ask questions and even contribute features to a wish-list.
Check your Start Menu for Programs->dynaTrace->dynaTrace AJAX Edition and launch it from there. The client will come up with the Cockpit and the Welcome Screen. Before we start tracing Google Maps lets explore some of the data collection options we have:
dynaTrace uses so-called Run Configurations that allow you to browse directly to the website you want to analyze without entering the URL in the browser every time. You can manage your Run Configurations (adding new ones, modifying or deleting existing ones) through the drop-down menu of the top left toolbar button. Selecting Manage Run Configuration allows you to pre-configure http://www.google.com as shown in the next screenshot:
As you can see from the screenshot above it’s also possible to let the AJAX Edition clear the browser cache before we start tracing the web site. This can be very useful when you want to test how your web site performs with an empty browser cache. Another important thing to know is the Preference Dialog that you can launch from the right most toolbar button.
You can specify several different settings here. Worth noting is the option to turn on/off argument capturing of JavaScript & DOM method calls as well as turning on/off JavaScript traces in general. For this exercise make sure you have Argument Capturing turned ON.
Let’s get going now. You can either select the Google run configuration from the toolbar, click on “Start Tracing” in the Welcome screen, or simply press F4 (shortcut). What happens next is that the dynaTrace AJAX Edition launches a new instance of Internet Explorer. Depending on whether you chose to clear the browser cache, it is doing that now (that may take a couple of seconds) before it browses to http://www.google.com. You can tell whether the dynaTrace AJAX Edition is actively tracing the browser by the changed application icon of IE – you should see a small dynaTrace icon on the top left corner of your window as well as a dynaTrace AJAX Edition toolbar telling you that you are connected:
If you do not see this happening please check out the General Usage Question section on the Community Forum for troubleshooting tips or contact us via the contact form or community forum. Here is the scenario that I want you to go through now:
This was my test scenario. Before we close the browser you can take a quick peek to the dynaTrace AJAX Edition and you will see a node under Browsers indicating that it is currently collection information from an IE instance. We could analyze the data while we are still running the browser or we can just close it and analyze the data that we have captured. Let’s do that – lets close the browser and switch back to dynaTrace AJAX Edition.
The recorded events in the browser have automatically been stored in a session that allows us to analyze the activities that have been captured without having an active browser. In the cockpit you can either double click the session or expand the session node and double click the Summary node. Both actions will bring up a Summary View which gives us a high level analysis of all activities in the recorded session:
The Summary View shows information for all visited URLs in the recorded session. Clicking on the individual visited URLs in the top table updates the charts and timeline visualization in the bottom to only show the data of the selected URL. In this overview we can see:
In our example the following things attract my attention:
The Timeline View can be opened for the complete session by double clicking on the Timeline node in the Cockpit. or you can open it for a single URL via the context menu in the Summary View. Let’s do that for the maps.google.com page:
The drill down opens the Timeline view for that particular page, automatically showing splitting network requests in individual domains. Via the toolbar and context menu you can turn on additional options like color-coding of content types and JavaScript triggers, or showing additional events like mouse moves, clicks and key strokes. The following screenshot shows the timeline with the additional options turned on:
We can make the following observations on that view:
Let’s zoom in to the timeframe of the first mouse click till the XmlHttpRequest. In my case this is the timeframe from second 11 to 12. Zoom in by pressing the left mouse button at the start time and drag your mouse to the end time. When you release your mouse the view will be zoomed in that timeframe like shown in the following screenshot:
The timeline now shows the click event, an XmlHttpRequest event followed by an onError and later on another XmlHttpRequest (XHR). Hovering with the mouse over the events shows us on which DOM elements the events were actually triggered. Hovering over the JavaScript shows us how long it took to execute the event handlers and hovering over the network request shows us which additional resources were downloaded. We also see what type of Rendering the browser had to do. We learn that the first click event handler causes additional content to be downloaded – including another JavaScript file from maps.gstatic.com. The execution of this JavaScript file – once it has been downloaded – triggered an XHR Request. We also see that the onError event handler is triggered and runs for 240ms.
From the Timeline view (as from other views as well) we can now drill deeper into the individual activities and see what JavaScript has actually been executed on those triggers and which JavaScript actually sent the XHR request. If you right click in the Timeline you can choose “Drill Down to Timeframe” bringing up the PurePath view showing all activities in the current zoomed timeframe – just like this:
In the top view we can see all activities in the browser in the selected timeframe including JavaScript executions triggered by the script tag or event handlers. It also includes Network requests and rendering times. The Stats column highlights whether timers or AJAX requests have been triggered by this specific JavaScript execution. The color coding highlights those activities that contributed more to the overall response time than others.
Selecting an activity in the PurePath List updates the PurePath or Tree with the actual JavaScript trace that was executed by the current selection. The PurePath Tree shows the actual execution path of the JavaScript code including timings of each individual method execution and its method arguments and return values (in case we have turned on argument capturing as discussed in the second step). The trace also follows timer invocations and shows these invocations as part of the tree. Not only do we see JavaScript methods but also access to the DOM and AJAX calls via XmlHttpRequest.
Let’s take a step back and switch to our previous Timeline View. I am interested in this AJAX Request that is sent. A double click on that icon in the event row opens a new PurePath view and it finds the place in the JavaScript trace that actually executed this XmlHttpRequest:
On the top we see which JavaScript file executed this code – check out the Details column. In the tree we see the full JavaScript trace that led to this XHR Request including method execution times as well as method arguments. The duration column tells us that this JavaScript execution took 1127ms in total. This also includes the time it took for the XHR Request to return as well as time waiting for JavaScript timers. Opening the details on this Network Request shows us Http Request and Response headers, exact timings of the request including Connect, Wait, Server and Transfer time and it also includes the actual content from the server.
The interesting thing with this request is that it took the server 372ms to respond an empty JSON object. From here we can continue our analysis and see what is actually done with the AJAX Response. In the PurePath tree we drill down the JavaScript trace to the actual onreadystatechange handler. The following image shows this handler in the tree as well as the actual source code on the bottom right:
What is very interesting here is that the contributor list on the bottom left shows us all the JavaScript activity in the currently selected subtree. The topmost shows me that a dynamic script tag is used and the source is changed to a JavaScript file to be dynamically downloaded by the browser. A double click on that top line in the contributor list automatically sets the focus to this method in the PurePath tree:
Here are my observations on that view:
The PurePath view offers several different ways to analyze the data. You can filter and search for items in each table and tree by simply typing the text you want to find or filter. Via the context menu and toolbar buttons additional filters can be specified to control the information that should be displayed.
The Network View shows all Network Requests that happened either in the whole browser session or on individual pages. Open the view via a double click on the Network node in the Cockpit on your left or with a Drill Down from the Summary View on a particular URL. In our example I go back to the Summary View and Drill into the Network of the maps.google.com site:
This view color-codes every request and highlights those in red that took the longest to download. By default this view is sorted by the Time Chart column which then shows the sequence of network requests as they were requested by the browser.
For every individual network request we see whether the resource actually came from the Browser’s cache (Cached column), Type of Request (Network or AJAX), HTTP Status, Mime Type, Size, detailed download timings broken down in DNS, Connect, Server Time, Network Time and Wait Time. On the bottom the HTTP Request and Response Headers as well as the actual response content is displayed. The interesting observation on this page is the waiting time for those objects retrieved from mt0.google.com and mt1.google.com. Every browser has a limitation on the physical network connections to a single domain.
In my case (IE7 on WinXP) it is 2 connections per domain. 20 png images are downloaded from these two domains. Due to the connection limitation only 2 images can be downloaded in parallel from each domain. The other images basically have “to wait” for a connection to become available. That explains the “waterfall” effect of these images and the increasing wait time. We would not see this effect as strong as it is here when working on different browser with different numbers of connections. Solutions to this particular problem are the use of Domain Sharding or CSS Spriting.
As from any view, a drill down from here to the PurePath view is possible. Let’s locate the 2nd AJAX Request we have on that page. Sort the Kind column and pick the one that responded with text/xml. Via the context menu we can drill into the PurePath View and get automatically pointed to the JavaScript trace that executed this request via XHR.
If you have dynaTrace APM running on your Application Servers you can even drill down to the Server-side PurePath showing you the actual Java or .NET Code that is executed on the server side to fulfil this AJAX Request. For a quick 2 minute video overview of dynaTrace APM and the PurePath technology check out the 2 minutes explainer.
The last interesting view is the Hotspot View. Open it via the Cockpit or from the Summary View to analyze a particular URL. In this example we open the HotSpot from the Cockpit to analyze all JavaScript, DOM and Rendering activity on all pages that I’ve visited:
The top table shows all JavaScript, DOM and Rendering activities in an aggregated way. We see that we had 103 Drawing Activities, 946 Reflow Activities or 1293 invocations of an anonymous method on a div tag. The list is sorted by the overall execution time showing the highest performance contributor on top.
Double clicking on one of these elements shows the back and forward traces. The back traces show who actually called these activities and the forward traces show what other activities have been triggered by this activity. The bottom view shows the JavaScript code of the selection in either the back or forward trace tree. I double clicked on the 946 instances of reflow activities. Reflow happens in the browser when images or other objects get loaded and when styles are applied. But – it also happens when accessing certain DOM properties or calling DOM methods. The back trace shows me that reading the offset or height properties cause a reflow in the browser’s rendering engine. Drilling further back I see which JavaScript methods actually do the DOM access. From the top the contributor table drilling into the PurePath is possible. Drilling in will open up those PurePath’s that include calls to the selected method – similar to our previous drill down for the XHR Request
Besides of manually collecting performance data with the dynaTrace AJAX Edition it is possible to automate the collection in scenarios where a testing tool is driving the browser instead of a human being. When running your test scripts with tools like Selenium, Watir, WebAii, … dynaTrace AJAX Edition can automatically collect the performance information for every browser session that is driven by these test tools. Check out the 5 Steps to Automate Performance Analysis Blog that shows AJAX Edition’s automation capabilities with Watir.
Collecting information and having it available for offline analysis are abilities of dynaTrace AJAX Edition that we have just walked through. If you identify a problem in somebody else’s code or if you want to share your findings with your colleagues, you need an easy way to share your collected data. This can be done by exporting your sessions to a session file. This can either be done via the context menu on a session in your cockpit or via the toolbar. The same is true for importing the file. Either use the context menu on the Sessions node in the Cockpit or use the Import Toolbar button:
You can now download my session that I used in this blog. Extract the zip file and import the .dtas file on your local machine and follow my analysis steps.
The dynaTrace AJAX Edition is a great tool for analyzing and troubleshooting Web 2.0 Applications in Internet Explorer 6, 7 and 8. The first official version has been strongly driven by the community that worked with the previous alpha versions. We encourage everyone out there to actively participate in driving this product forward by providing feedback through the Community Pages and report problems through the built-in report feature accessible in the toolbar:
These three toolbar buttons allow you to share the product with a friend, give us feedback and report a problem. Many of our current clients use the AJAX Edition to identify and solve problems in their browser frontend components and we’ve gotten some great feedback from them so far. These clients also use the integration to the dynaTrace Continuous APM Solution which gives them full end-to-end visibility from the browser into their backend. Thanks for following me all the way down through this rather lengthy Step-By-Step Guide. Feedback on this blog, on the tool and on your own experience with the dynaTrace AJAX Edition as well as other tools that are out there are highly appreciated and welcomed.