
JavaScript is only one actor in a much bigger performance. It plays a role, but is dependent upon its support cast (Style Sheets, HTML). The best JavaScript code will be useless when combined with poorly structured HTML and badly written CSS. Likewise, the most logically structured XHTML will perform badly if combined with poorly written JavaScript. All three elements need to pull together to make a well functioning and rich user interface.
HTML user interfaces are constructed from three unique yet interdependent elements:

These three items are interdependent but the user interface should be constructed to function without the JavaScript and CSS. The principle of “progressive enhancement” is based on the idea that you should begin with your core content. The core content is structured using markup. That marked up content is then enhanced. That enhancement might be stylistic, using CSS, or it might be behavioral using DOM scripting.
“Unobtrusive JavaScript” is a generic term that can be applied to web sites which use JavaScript in such a way that if it was removed the site would still be accessible and functional:
“A scripting technique that separates behavior and structure and makes sure the user agent is capable of supporting the script before it is applied. Web pages using unobtrusive scripting are usable without JavaScript, but offer a richer user experience when JavaScript is supported.”
The great trend in the past several years has been to remove the aesthetic design concerns from HTML and centralize the style of the user interface in cascading style sheets. It follows that we should also attempt to decouple the behavior of the user interface from the HTML as well. The benefits of this are:
This is covered in the later section on AJAX issues, but is core to unobtrusive coding practices in JavaScript. All key functions should be able to operate without the use of JavaScript. Forms that update server-side data should be able to do so when a form is submitted, searches should yield results without JavaScript as the middleman. Browser users are accustomed to user interfaces working linearly. “view a n interface… do an action… refresh the interface”. For this reason all core interaction should occur in a linear fashion. This will allow for bookmarking, and the use of the forward and backwards buttons which are built into browsers and are part of the user experience (and used by a surprising number of users to navigate the browser history).
All JavaScript behavior should be independent from the structural XHTML/HTML document. All behavioral rules should be set, declared, and initialized from the JavaScript document. This aids future changes, additions, and updates/rewrites of the behavior. It also enables the structure to change independently, and yet still inherit the behavioral rules which applied to the original document.
As with all coding languages, it is possible to write code that has the same outcome, but in one instance it will run in milliseconds and in the other it could take minutes.
JavaScript is particularly fickle, as it is dependent not only on how the code is written, but also how the JavaScript engine interprets that code- and many browsers use different engines that have different approaches and different time implications. So it is possible to take the example above, and produce the same outcome from identical code running on two different browsers.
There are many shortcuts, techniques, tricks, or hacks, that can be employed to get JavaScript to run quickly across browser. Not every ‘new’ feature of the language is the best for it’s purpose, and not every ‘correct’ way of doing things will be the fastest in all browsers. Documenting these could be a hefty white paper in itself.
Suffice to say that the pure JavaScript code needs to be optimized to work in target browsers, and developers need to take the browser’s unique capabilities and shortcomings to heart when building their scripts.
In time-sensitive development environments, optimizing all aspects of the JavaScript code can typically become a lower priority than getting a finished product that works. In this case optimization should occur at a re-factoring stage in the development process, so even if time is short you have a functioning application:
We would suggest the development team setup a cross-browser test environment in which multi-technique benchmarking of key functions can be rigorously tested prior to development. For example, if your application will use extensive AJAX tasks, it is worthwhile building small easily controlled test examples of the various techniques (XSL-T processors in IE vs. Firefox’s equivalent vs. pure JavaScript). These controlled examples can be run multiple times, and definitive test results can offer quantifiable conclusions which may influence the direction of the real-life coding effort.
Ever since Jesse James Gardner coined the phrase AJAX (Asynchronous JavaScript And XML) on February 18th of 2005, the web world has fallen in love with this technique- which has been part of JavaScript IE supported AJAX0-like functionality in IE5 in 1998. Mozilla included HTTP Requests in 2001. But the new marketing hype, driven by it’s successful implementation by the likes of Google, Flickr, and Yahoo, has also led to many fundamental AJAX errors being made.
For AJAX to work it requires a very finite set of circumstances, as it’s very dependent on browsers and browser configuration (JavaScript turned on, ActiveX turned on in IE, etc).
Does the added benefit of AJAX actually outweigh the technical constraints placed by point 1, the added cost of developing in AJAX, and the added user confusion when their browser experience fundamentally changes?
AJAX adds another layer of complexity to applications that could already be very complex. If you use script callbacks you can end up feeding your main HTML and your HTTP responses for the AJAX requests, generating two separate HTML responses for a single user interface. For anything more than simple interaction this can lead to monstrous client loads handling large numbers of AJAX callbacks.
AJAX often replaces server side functionality, yet often requires considerably more code to achieve the same results. In addition, code run on a client is dependent on the client machine and it’s speed, whereas the server is a controlled and known environment, that is tuned specifically to run the scripts you pass it.
Any inefficiencies in an AJAX application will be magnified on the server side, which can lead to higher than expected server load. Single user interface loads are often handled more efficiently than a user interface that is constantly posting back to the server for smaller atomic pieces of data.
Excessive use of AJAX can lead to an inconsistent User Experience. A prime example is the old issue which UI Specialists had with single page, Flash-based applications. That is, the user would navigate through a web site, then hit the back button expecting to return to their previous location within the flash UI, only to return to the previous page in their browser history.
AJAX doesn’t refresh the user interface. On face value this might be a good thing, except that the web browsing norm is that the user does something and a user interface refreshes showing the outcome of their action. Often with AJAX there is little or no indication to the user that something is happening, this can lead to user frustration, as they think the application is not responding when in fact it’s just refreshing in the background.
AJAX is an excellent tool to enhance a web applications interactive abilities. It should not replace a web application’s functionality, but enhance the behavior of the application.
AJAX is excellent at giving rapid in-session feedback to a user’s input (telling them their credit card number if not the correct format before they submit the purchase, suggesting alternative search terms as users type into the search field, etc.).
JavaScript is one of the more complex languages to write definitive best practices for. It is reliant on browser technology that could interpret code differently to it’s intended purpose, run code at different speeds or not run code at all.
This being the case, JavaScript development needs to be approached from a per-case perspective but with some fundamental architectural factors:
When used in conjunction with XML-HTTP requests, JavaScript is a powerful tool for enhancing the user experience - but it should not be an alternative to traditional browser interaction.