It is for the first time that I attended and presented at a web-developer conference. That too, one of the conferences which surely sees amongst the major turnout of JavaScript influentials - “The AJAX Experience 2008”.

 

My talk was around "Analyzing the AJAX Application Performance". Here is the slide deck I used for the presentation. Also, following are some notes from my presentation which I hope web developers would find useful.

 

This talk was divided into three sections:

  1. AJAX subsystems: Presents an analysis of the Internet Explorer browser sub-systems that impact to AJAX application performance.
  2. JScript Profiler: How to fine tune your AJAX application performance with the new easy-to-use JScript profiler which come in-built with IE8 Developer Tools
  3. Enhancements to the JScript Engine - Native JSON support: Nuances of Native JSON support that is now available in IE8 Beta2

 

Section 1: AJAX Subsystems – AJAX Stack for Internet Explorer

As modern AJAX application become more interactive and richer, performance of these applications is very important to deliver a great user experience. While a fast and powerful scripting engine does impact the performance of an AJAX application, many other sub-systems of the browser contribute to the overall performance of the application. Due to architectural differences these sub-systems often vary across browsers architectures. While in essence all browsers would have the similar functionality, and may be even a similar AJAX Subsystem Stack, the talk focused only on various sub-systems for the Internet Explorer.

 

An AJAX scenario can be visualized as an activity passing through a pipeline of logical subsystems within the browser stack. In order to understand the performance characteristics of AJAX applications, we need to understand what each of these sub-systems do and how they interact with each other.

 

The flow of the AJAX scenario across the various components of the pipeline is as below:

Network: Whenever a user types in a URL to load a web-page, the browser communicates with the server over the network, and waits for a response from the server. The network is also responsible for asynchronous data exchange between the web client and the server.

Parser: When data is received from the server, it reads, analyzes, and converts the data (HTML, CSS, XML, etc.) into their native object model formats.

Layout: Internet Explorer’s layout subsystem takes input from the parser and computes the layout of the various components which form the web-page.

Rendering: Internet Explorer’s rendering engine does the final painting of the page (and any subsequent updates that are required).

Native OM (or DOM): The Native Object Model is the object representations of the web site's HTML and CSS content. The Native OM component also acts as a layer for communication between different browser components and acts like the nervous system, which controls the message flow to all the components within the AJAX subsystems.

JScript Engine: The JScript engine contains the basic primitives (functions, objects, types, etc.) for performing various language operations. The JScript engine is also responsible for asynchronously exchanging data with the server. In terms of script performance, apart from the engine, performance is also dependent upon the application code. I covered the details around this in Section 2 below.

Others: These constitute Internet Explorer’s Event and Error handling infrastructure, wait/idle time, etc.

Misc/OS: The browser is dependent on certain functionality provided by the Operating System like threading, process handling, memory layout, cache size etc

 

Keeping the above information in mind, I picked 30 sites to showcase the performance across subsystems. We measured AJAX sub-systems time profile using the ETW (Event Tracing for Windows) infrastructure in Internet Explorer 8.  Using ETW events that mark off AJAX sub-systems, we can accurately measure time spent within each AJAX subsystem, including CPU and elapsed time and this data can be collected while running any scenario. The process in each of these 30 cases was to clear the cache, launch IE8 with a blank page, navigate to the site, wait for 45 seconds (to let any animation/layout settle down) and exit.  Each test is run 3 times and the sub-system profiles are averaged and the run that shows the time closest to the average is used for the analysis.  

 

These numbers are collected per scenario and these numbers might vary across scenarios on each site. While this data is not to undermine the importance of any of the subsystems and the possible impact that they would have on the AJAX Application performance, with an improvement in their performance, it does show that measuring only one of these subsystem’s performance cannot be classified as measuring the performance of the entire AJAX stack.

 

Section 2: JScript Profiler: How to fine tune your AJAX application’s performance with the new easy-to-use JScript profiler which come in-built with IE8 Developer Tools

There are various Javascript profilers currently available in the market. These broadly fall into two categories:

·         Source code instrumented

·         Script engine instrumented

Source code instrumented profilers: These profilers work by modifying the source code to add specific code that measures the timestamp.  The simplest form of this kind of profiler is to insert a code  

var t1 = new Date();

// code to be measured    

var t2 = new Date();    

alert(“Time: “ t2 – t1);

More often, these profilers provide an automatic way to instrument the source code on the fly (often using a proxy server). The profile data is sent back to the server for analysis profile reports are generated by downloading this data from the server. One such profiler is AjaxView.

 

Because the instrumentation is usually written in JavaScript and usually involves making a DOM/ActiveX call, the overhead of profiling is high – sometimes higher than the code being executed.  [Though the overhead can be accounted for while making the calculations, it is usually not very accurate.] Also, since the code is instrumented before the browser gets the data, any dynamic code generated on the fly within the browser (like eval) are usually not instrumented and cannot be measured.

Script Engine Instrumented: These profilers work in tandem with the script engine which exposes profiling information through some API.  The script engine may use on of the following techniques for profiling:

       Directly export profiling data (like the number of times a function is called, time spent in the function, etc), or

       Provide a callback which is called when the script engine performs a specific task (like a function call begins or ends), or

       A mix of both of the above.

The JScript engine introduced API’s in IE8 Beta 2 to provide callback to report profile information. This is designed so that third parties can build profilers (Logger and Profiler Core components) that use this API to capture profile data from the JScript engine. Because the callbacks are usually implemented directly in native code, the overhead is kept low.  And since the callbacks are directly issued by the engine, it provides better functionality

       Dynamic code can be profiled

       Built-ins can be profiled

       Measure non execution time of the engine – like parse, GC etc.

 

Advantages of the JScript Profiler:

·         Easy to use

       Start and Stop profiling with a single click,

       No need to install, no need to setup – the profiler comes free with the browser

       Lightweight

       Since there is no extra code script that is being introduced in the application, the profiling overhead is really low

       Provides profile report in two views

       Functions View: Provides a flat listing of all the functions and is useful to spot “generic” functions called from different locations

       Call Tree View: Hierarchical listing of functions based on call execution and is usseful in finding the call stack that has greatest performance impact

       Supports Multiple reports

 The IE8 Profiler can keep track of multiple reports to be viewed at once.  This is especially helpful in comparing the data – say, after you made some changes in your code.

       Export data

 In case you want to analyze your data further, it allows the data to be exported to a file in CSV format. With this data persisted in CSV format, users could

       Analyze the data further

       Make graphs

       Automate

       Page navigation

For every page navigation, IE8 creates a new instance of the script engine.  The JScript Profiler makes sure that the data is not lost when the script engine is destroyed.

       Built-in methods

Usually, built-in methods are extremely fast.  And web developers don’t have control over how these methods are implemented.  However, in certain cases, it helps to know how built-in methods are called by the script engine. The IE8 JScript Profiler captures the time spent in built-in methods.  This helps in understanding how the script engine works.  For example, it is possible that built-in methods are called implicitly.  E.g. A piece of code doing string concat might actually be calling Array.join multiple times.

Anonymous functions:

The world of javascript is littered with anonymous functions.  These functions have no name and the distinguishing factor is the place where these are defined.  This can be nightmarish for web developers if they have to refer to the function definition each time they have to look at the performance data.

 

IE8 Profiler comes with an innovative solution for this: anonymous functions are given a name wherever possible.  This is done by implementing a simple heuristic logic.  E.g.

    var Shape = {
        Area : function () { . . . } // anonymous function 1
    };
    Foo = function () { . . . } // anonymous function 2

The two anonymous functions are named “Area” and “Foo” respectively.

A few facts about name inferencing:

       The heuristic may not work in all cases like pure anonymous functions and script blogs

        The logic is kept simple so that we don’t incur a big performance penalty

 

Internals of the JScript Engine:

The profiler consists of the following components:

       Host (Web Browser) (Internet Explorer)

       Script Engine (JScript engine)

       Logger (A COM Component)

       Profiler Core

       Profiler GUI

 

The host provides the context for the script engine.  It creates the script engine as and when necessary and feeds scripts to be executed. The script engine provides an API through which profiling can be enabled or disabled.  When profiling is enabled, the engine creates a Logger through which callbacks are emitted. The Logger is a COM component which handles callbacks from the script engine, and logs the performance data.  When a user stops the profiling, the Profiler Core component aggregates and analyzes the performance data from the Loggers.  It combines the performance logs and makes a report out of it. This report is then displayed in the IE8 Developer toolbar using the Profiler GUI component.

 

The two profiler API’s that are exposed are:

       IActiveScriptProfilerCallback

       IActiveScriptProfilerControl

While the IActiveScriptProfilerControl is mainly responsible for starting and ending the profiling session, the IActiveScriptProfilerCallback handles callbacks from the script engine and is used to log performance data. The two API’s are designed so that third parties can build profilers (Logger and Profiler Core components) that use this API to capture profile data from the JScript engine.

 

Section 3: Enhancements to the JScript Engine - Native JSON support: Nuances of Native JSON support that is now available in IE8 Beta2

 

JSON is slowly and steadily slated to become the de-facto wire format to transport data to and from AJAX applications. This is mainly due to three reasons

       Simplicity: JSON follows a JScript like format. JScript developers feel at home with JSON as compared to XML

       Security: It is more secure than non-native implementations as it avoids eval. This means if evil code is sent to the JSON parser, it would never be eval(ed)/executed.

       Performant: It is faster than Eval based parsers implemented in Javascript and XML

 

The native JSON support in IE8 is based upon EcmaScript “3.1” proposal (as implemented by Douglas Crockford’s json2.js). We looked at the various JSON formats, both proposed and implemented before introducing the native JSON support in IE8. Given that the ECMAScript steering committee was already working on a JSON proposal for ES3.1, we decided to stick to the same, and follow the same API.

 

How to use it: The Jscript engine now has a new global JSON object. So if the web applications need to take advantage of the native JSON implementation, they would need to ensure that they do not overwrite the name space. The JSON object exposes two API’s - JSON.parse and JSON.stringify. JSON.parse deserializes a JSON text to a JScript value – which is either an object or an array. The optional reviver parameter is a function use to transform the result. The JSON.stringify on the other hand serializes a JScript value to JSON text. The replacer parameter is either an array or a function used to transform the results, and the space parameter is used to add appropriate indentation like spaces, newline character etc. to display the serialized JSON text in a more human readable format.

 

The native JSON support is made available in all IE8 modes. The main reason for the same is to allow developers to take advantage of this performance/language enhancement, while running in non standardards mode too.

 

The native JSON support provides over 10x speed gains while serializing the data as compared to JavaScript based serializers. It also provides ~3x gains during deserialization, when compared to JavaScript based parsers or XML.