10 things AJAX developers MUST know

1) Ajax is an idea, not an acronym

While Ajax commonly is spelled out as Asynchronous JavaScript and XML, the full name is not entirely appropriate because it oversimplifies the history of the technology and the implementation options that lie at its heart. More exactly, Ajax encompasses the idea that Web applications can be built to opt out of the typical post-wait-repeat cycle used in server-side-focused Web applications. Ajax lets Web applications move to a more responsive, continuous, but incremental style of updating. Ajax provides users a richer, more interactive way of experiencing the underlying Web application. This goodness for the user might mean that more monitoring and security oversight might be required of network professionals, as well as, potentially, server and network alterations.

2) It’s really all about JavaScript

Ajax applications are written in JavaScript and usually rely on the XMLHttpRequest object for communications, which is making its way through the World Wide Web Consortium process. Because, like many Web technologies, it now is only an ad hoc industry standard, notable differences can be found in various browsers’ implementations of it. It’s also possible to use other data transport mechanisms — with and without widespread industry support — with Ajax applications, including traditional frame and image-cookie methods, as well as the use of binary bridges to Flash or Java.

Regardless of the transport approach used by the developer, Ajax has raised JavaScript to a more important position within a Web application than it previously held. JavaScript now is responsible for important data-collection, communication and consumption duties, so it no longer can be treated as a second-class Web technology without serious repercussions.

Developers who think the JavaScript technology is toxic can try to avoid the language by having a tool or framework generate it from some other language like Java (Google Web Toolkit, for example), or hide the code behind components or tags (such as with .Net or Ruby). At the end of the day, however, JavaScript still will be in the application. It’s better to understand the language and embrace it directly, because if you are going to use Ajax, you ultimately are using lots of JavaScript.

Ajax is intertwined with the network, so bad code is going to mean lots of troubleshooting by network administrators, as well as developers: The bottom line is to encourage good, network-aware coding! The same organizational "rules and tools" — coding standards, testing regimes and source-code control — that are in place for other languages must be applied to JavaScript to ensure that Ajax applications are supportable and robust.

3) XML is not required

Despite the "x" in the acronym, Ajax does not require XML. The XMLHttpRequest object can transport any arbitrary text format. For many Ajax developers, JavaScript Object Notation or even raw JavaScript code fragments make more sense as a data format, given that JavaScript is the consuming environment. For direct input into documents, other developers may favor raw text or HTML fragments. Still others will use such data formats as the less-known YAML markup language or such old standbys as comma-separated values.

Of course, it is possible and certainly reasonable to use XML, but it is far from required. Using binary formats for uploading files is not supported yet by the XMLHttpRequest object, but considering that Flash uses a binary format called Action Message Format, it is likely that similar features will be found in Ajax applications soon enough. You should know which format is being passed around the network, because it isn’t always XML. Also, make sure you can analyze the format for performance and security.

4) Plan for an increase in HTTP requests

The most obvious issue for the network administrator supporting Ajax applications is that the architectural programming pattern has changed the network utilization of Web applications from a batch-like, somewhat infrequent response of a few hundred kilobytes, to a more continuous exchange of smaller HTTP responses. This means that network-bound Web and application servers may find themselves even busier than before. What Ajax will do to your server and network utilization certainly will depend on how the application is built — make sure your developers understand the network impact of their applications.

5) Optimize Ajax requests carefully

Web applications should adhere to the network delivery principle of sending less data, less often. That doesn’t mean that this principle is widely followed by developers, however. Fortunately for the network, HTTP compression of Ajax responses can reduce response size and is supported in all modern browsers. Because of dynamic compression’s overhead, however, speed may not improve much if responses are indeed relatively small. This means that it would be wise for network administrators to turn on compression on their Web server, but they need to understand that with Ajax applications, their gains won’t be as big as with traditional Web applications.

To send data less often, we generally would employ caching. Most Ajax implementations can be openly hostile to caching, however, given certain assumptions made by browsers regarding not re-fetching URLs during the same session. Rather than work with caching, many Ajax developers will work aggressively to defeat caching via the header setting or URL uniqueness.

It is possible to address caching concerns with a client-side Ajax cache written in JavaScript, but most Ajax libraries do not implement such a feature. Network professionals should show developers the benefit of caching, because Ajax probably will benefit more from that than from compression.

6) Acknowledge the two-connection limit

Ajax applications are limited by HTTP to two simultaneous connections to the same URL. This is the way the HTTP protocol is designed, not some browser bug or limitation. The good news is that it keeps many Ajax developers from swamping a server accidentally, though Microsoft’s Internet Explorer 8 is supposed to go well beyond the limit. Chatty Ajax applications can be trouble, and with browsers changing the rules, network administrators need to keep a close eye on the number of requests made, and work with application developers to avoid employing such design patterns as fast polling or long-held connections.

7) Watch out for response ordering

With traditional Web applications, the network effects of TCP/IP communications — such as the lack of order in which individual HTTP responses are received — generally are not noticed by developers or users. The base unit, the HTML document, is received before other objects, and it then triggers the request. Any subsequent request triggers a whole new base document, thereby guaranteeing order. Ajax takes such implicit ordering away, however, so that an application dependent on proper sequencing requires a response queue. Ajax frameworks, however, are not consistent in acknowledging this network concern. So, again, make sure Ajax application developers understand such network-level concerns.

8 ) Acknowledge the effects of eliminating "Layer 8" error correction

For years, users have been correcting Web-delivery quality by reloading pages or pressing the Back button. Simply put, users doing this help mitigate network problems because errors occur generally at expected moments between page paints. With Ajax, however, application failure is no longer that obvious. Worse yet, users often are misinformed about errors, because the simple, animated-GIF spinning circle provides little information about the true status of the request.

Developers are at a loss because many libraries aren’t effective at acknowledging that timeouts happen, retries must occur, and server and data errors crop up. JavaScript diagnostics showing communication and code errors are rarely in place on the client side, so blissful ignorance is the norm. More application-level monitoring is required for administrators to support Ajax properly.

9) Old security threats get a second exposure

If you listen to the pundits, Ajax may appear to produce more attack surface, but it really isn’t any less secure than traditional Web-application development environments, because the HTTP inputs to the trusted server side are the same — headers, query string and message body. If implicitly trusting client-side code and entered data is not verboten already in your Web development group, however, Ajax may push things in that direction.

Cross-site scripting (XSS) isn’t a vulnerability new with Ajax; it is just more common, especially if an application allows state data to be manipulated with JavaScript. HTML input should be disallowed in most cases, and HTTP Only Cookies should be applied immediately to reduce cookie hijacking and other attacks via XSS.

Cross Site Request Forgery likewise isn’t new with Ajax, but if your application developers aren’t checking the HTTP Referer (sic) header and managing sessions properly within Ajax applications, you’ve already been open to it, although it might be worse now.

Hackers, like developers, now are more interested in using and abusing JavaScript, which increases the potential for exploits. Network professionals should make sure developers are aware that client-side code can be manipulated even with obfuscation in place, so data inputs should always be filtered and sanitized, Ajax or not.

10) Abide by same origin for your protection

On the positive side of security, JavaScript’s same-origin policy (SOP) is fully enforced in an XMLHttpRequest-based Ajax application. This policy makes sure that scripts cannot talk to domains outside of those from which they are issued. From the developer’s point of view, this can be quite annoying because it means that pages served, for example, from ajaxref.com can’t talk to a URL hosted on www.ajaxref.com; even if it is the same machine, it isn’t the same exact domain. DNS equivalency doesn’t matter here; it is a string-check employed by the SOP.

The SOP will severely hamper a developer’s ability to perform some Web-service efforts on the client side as well. Clearly the best approach is to use a proxy on the server to bounce requests to other servers and combine the results. However, many Ajax developers attempt to break the same-origin restrictions. Using the <script> tag as a transport instead of the XMLHttpRequest object introduces dangerous trust assumptions, and that leads to the origin of much of the concern about overall Ajax security.

Now, with such browsers emerging as Firefox 3 and Internet Explorer 8 employing native cross-domain request facilities, there is certain to be more trouble on the horizon. As is the case with Java’s security-sandbox concept, SOP restrictions are introduced just to keep developers from destroying security. Go around such safeguards with extreme caution.

Watch what you wish for

With Ajax, rich-application widgets will win a project, but bad plumbing may sink it. If the promise of a rich Ajax application is delivered in a network environment that is occasionally fragile, users will become disillusioned with the perceived instability of the application regardless of its slick interface. To enable desktop-like quality, network professionals must educate Ajax developers about certain network and security fundamentals and provide a solid and constantly monitored delivery platform that includes client-side diagnostics on JavaScript functioning and network performance from the user perspective. Users regularly see rich Web applications done right — like those coming from Google, for example — so anything less is a risky endeavor. 

Ajax Performance Analysis

Posted on April 29th, 2008 in AJAX (Asynchronous JavaScript and XML) by Ashish  Tagged

Asynchronous JavaScript + XML (Ajax) continues to raise user expectations for interactivity and performance, and developers are increasingly treating Ajax as a must-have component of their Web applications. As more code is moved  client side and the network model changes, the community is responding by building more tools to address the unique performance challenges of Ajax. Examine toolsets that find and correct performance problems within your Ajax-
enriched applications.

Performance is one of the primary motivations for enhancing applications with Ajax. Ajax can improve response time by communicating with the server without full-page requests. By reducing response time, Ajax can provide a significantly better user experience. However, analyzing and improving the performance of Ajax applications requires a different toolset than traditional Web applications. This article examines these tools and shows how to use them to find performance problems and make corrections.

An Ajax application’s performance is based on several aspects of a Web application:

    * Server response time
    * Network transfer time
    * Client JavaScript processing time

In traditional Web application development, server response time is the primary focus for performance analysis. Most performance analysis measures the application server’s ability to quickly handle requests, carry out necessary application logic, and generate a response. In Ajax application development, this is still a critical aspect of the application’s performance but is generally well understood.

The tools

To understand what aspects of a Web application you need to improve, you must properly analyze the components of the application. This article looks at how you can use the Firebug extension to Firefox and the YSlow add-on to instrument a Web application. After you install these tools, connect to the site that you are developing and click YSlow on the Firefox status bar. This opens the YSlow interface in Firebug. Now click the Performance button. YSlow performs an analysis of your application and provides a report on the different parts of the network transfer time of your application, as Figure 1 shows.


Network transfer time

In most Web applications, network transfer time is the biggest bottleneck. With a YSlow report, you can analyze the different aspects of the network transfer to understand what can be done to decrease the transfer time.

Reducing HTTP requests

Every HTTP request requires some time for the request to be sent to the server and the response to be retrieved. Even when responses are small, there is still the baseline roundtrip time, which is referred to as latency. YSlow provides a grade based on how many HTTP requests are made. A large number of requests results in significantly slower load times. You can reduce HTTP requests by simplifying the page so that fewer components need to be loaded. You can reduce image requests by using CSS sprites. Tools that generate CSS sprites are available (see the Resources section). To reduce script and CSS requests, include them inline in the page or combine multiple scripts or CSS files together.

You can reduce HTTP requests by providing HTTP cache expiration headers with future dates that allow browsers to cache components. It is important that as a user navigates from page to page, or returns to visit your site, that components can be cached and do not need to be downloaded each time your site is visited. Proxies can also cache frequently loaded content if proper expiration headers are provided. An expiration header looks like this:

Expires: Wed, 10 Mar 2009 10:00:00 GMT

Remember that if you use far future expiration dates, browsers will still cache your content even when you have changed it. You may want to reduce the expiration to a day in the future. You can also change filenames when you version them so that new URLs are requested when a new version is released, and the browser has to make a new request. You can configure Apache to add expiration headers with an ExpiresDefault directive:

ExpiresDefault "access plus 10 years"

With YSlow, you can also look at the total download size of your page by clicking the Stats button. YSlow shows the size of the page for a first-time visitor (with nothing cached) and for subsequent page visits (when caching can be used).

Alternate DNS lookup

HTTP requests can involve more than a just a roundtrip to your server. If there are multiple host or domain names used by resources, the browser may need to do additional Domain Name System (DNS) lookups. YSlow alerts you if multiple names must be looked up. However, it is important to note that multiple DNS names can actually be a performance benefit as well. Most browsers only allow two connections per host name. But with multiple host names, more connections — and consequently, more concurrent downloading — can take place. 

Reducing the size of component transfers

In addition to reducing the number of HTTP requests, it is also advantageous to reduce the size of the components that are requested. Techniques can be applied to compress certain formats. YSlow indicates what techniques can be successfully applied to reduce response size.

You can shrink JavaScript code, CSS, and HTML by eliminating unnecessary whitespace and comments. You can further compress JavaScript code by renaming variables. Packer and YUI compressor are effective tools for JavaScript compression, and YUI compressor supports CSS compression as well. You can compare minifiers with The JavaScript CompressorRater.

One of the most effective ways to compress resources is by enabling gzip (short for GNU zip) for text-based resources. Using gzip, you can generally reduce content size by about 70%. Do not use gzip to compress resources that are already compressed, such as images and movies. Good candidates for gzip include CSS, HTML, JavaScript code, XML, and JavaScript Serialized Object Notation (JSON). Apache 1.3 supports gzip with mod_gzip and Apache 2.0 uses mod_deflate.

Not only is it important to minimize the size of HTTP responses in terms of resource size, but it is also important to minimize the size of HTTP requests. For many Internet users, upload speeds can be significantly slower than downloads, and so performance can be more sensitive to request size. Large URLs, large post data, and excessive headers can also increase the size of a request. In Firebug, you can go to the Net tab to view your requests, as Figure 2 shows. For each request, you can expand the request to see the request headers. One of the most common sources of unnecessarily large header sizes is large cookies. Cookies are included in the header on every request, and, therefore, large cookies add a lot of extra overhead.

Other network transfer performance improvements

Another YSlow recommendation is to use a content delivery network (CDN). A CDN provides a distributed network of servers with content that is closer to your end users for faster response times.

You can also improve the speed of rendering your Web pages by properly ordering your CSS and scripts. YSlow analyzes the position of your CSS and script declarations to provide information on how to improve the ordering. It is recommended that CSS declarations be at the top of the page so the CSS can immediately be used for rendering, and the scripts be at the bottom of the page so the page can render before loading the JavaScript code for interaction.

JavaScript processing time

After your Web page is successfully generated by the server and transferred to the browser, Ajax applications generally rely on JavaScript code for interactivity with the user. Most users are prepared to wait a little while for a page to fully download, but quality interaction depends on rapid feedback, so quick response to various components on your page can be the most important aspect of an enjoyable user experience. Also, browsers are usually still responsive when waiting for resources to download, but if JavaScript code is executing continuously, it can completely lock up the browser.

Firebug comes with a profiling tool. To use the profiler, go to the Console tab and click Profile to start the profiler. It may help to understand what part of your Web application makes heavy use of JavaScript code. The profiler also yields more accurate results if you can repeat the activity you are testing several times. For example, if there is a significant amount of JavaScript code that is executed when the page loads, you may want to do several page loads. If there are JavaScript hover event handlers, you may want to move the mouse around the page for a while to let the profiler collect a decent amount of information. When you finish your activity, you can click the Profile button again to display the profile results, as Figure 3 shows.


The profile result lists all the function calls that took place during the profile. Each entry shows the number of times that the function was called and statistics on the processing time for the function call. There is a Time column that indicates the total amount of time spent waiting for the function to return, and there is an Own Time column that indicates the total amount of time spent waiting for the function to return minus the time the function spent waiting for calls it made to return. Own time is generally the most important time because it represents where the majority of the expensive processing is taking place, and this time is what the values in the Percent column are based on. By default, Firebug sorts on the Percent column, with the highest values at the top. This is a convenient way to read the profile because the most expensive calls are on top, and you can focus your efforts on improving the performance of these functions. With Firebug, it is easy to go to the function source; you can simply click on the entry in the list to go to the function.

When evaluating the performance of your JavaScript functions, it is also important to note the number of times the function was called. If it is called a large number of times, the function itself may not necessarily be slow (you can see the average processing time for the function), but it may simply be called too frequently. Sometimes poor performance can be a result of a function being used more frequently than expected. Hover event handlers such as onmousemove often produce a large number of events.

If you can determine that a certain function is taking an excessive amount of time in processing, you may want to look at your JavaScript code for possible problems.

Table 1. Slow JavaScript operations

Operation Description
DOM access Interaction with the DOM is usually slower than normal JavaScript code. Interaction with the DOM is usually inevitable, but try to minimize it. For instance, dynamically creating HTML with strings and setting the innerHTML is usually faster than creating HTML with DOM methods.
eval Whenever possible, avoid the eval method because significant overhead is involved in script evaluation.
with Using with statements creates additional scope objects that slow variable access and create ambiguities.
for-in loops Traverse arrays use the traditional for (var i=0; i<array.length;i++) instead of for-in loops. Unfortunately, most JavaScript environments have a slow implementation of for-in loops.

Firefox with Firebug and YSlow is certainly the best choice for profiling. For Safari on Mac OS X, you can also use Web Inspector to analyze HTTP requests. For JavaScript performance profiling, you can use manual techniques to gauge the performance of certain functions. To instrument a function manually, you can measure the execution time with the Date function, as Listing 1 shows:

Listing 1. Manual method timing
               
function myFunctionToTest() {
    var start = new Date().getTime();
    … // body of the function
    var totalTime = new Date().getTime() – start;
}

One particular problem that can plague performance is the poor memory management of Windows® Internet Explorer®. Unpatched Internet Explorer 6 and prior versions exhibit progressively slower behavior as more objects and properties are created. As a general rule, if you have more than 5000 objects, old versions of Internet Explorer will be considerably slower.

Conclusion

Using Firebug and YSlow, you can thoroughly analyze your Web applications to make educated changes to improve performance. YSlow provides detailed information to assist in reducing network transfer times. Firebug provides detailed JavaScript profiling analysis to determine critical areas of code to improve. Together, these tools can help you build Web applications with performance that provides the highest level of user experience.