AJAX In Action [153]
NOTE
When writing an Ajax application, then, it is important to be aware of memory-management issues regarding DOM elements, as well as conventional variables that we create ourselves. We also need to take account of the managed nature of DOM elements and treat their disposal differently. When mixing DOM nodes and ordinary variables, the use of cleanup code is advised, to break cyclic references. In the following section, we’ll look at further considerations that the Ajax programmer needs to take into account when working with Internet Explorer. Further special considerations for Internet Explorer
Each web browser implements its own garbage collector, and some work differently than others. The exact mechanisms of the Internet Explorer browser garbage collection are not well understood, but, according to the consensus of the comp.lang.JavaScript newsgroup, it has specific difficulties with releasing variables where a circular reference exists between DOM elements and ordinary JavaScript objects. It has been suggested that manually severing such links would be a good idea.
To describe this by example, the following code defines a circular reference: function MyObject(id){
this.id=id;
this.front=document.createElement("div");
Licensed to jonathan zheng Designing for performance 311 this.front.backingObj=this; } MyObject is a user-defined type. Every instance will refer to a DOM node as this.front, and the DOM node will refer back to the JavaScript object as this.backingObj. To remove this circular reference while finalizing the object, we might offer a method such as this: MyObject.prototype.finalize=function(){ this.front.backingObj=null; this.front=null; } By setting both references to null, we break the circular reference. Alternatively, a DOM tree could be cleaned up in a generic fashion, by walking the DOM tree and eliminating references on the basis of name, type, or whatever. Richard Cornford has suggested such a function, specifically for dealing with event handler functions attached to DOM elements (see the Resources section at the end of this chapter). My feeling is that generic approaches such as this should be used only as a last resort, as they may scale poorly to the large document trees typified by Ajax rich clients. A structured pattern-based approach to the codebase should enable the programmer to keep track of the specific cases where cleanup is required. A second point worth noting for IE is that a top-level “undocumented” function called CollectGarbage() is available. Under IE v6, this function exists and can be called but seems to be an empty stub. We have never seen it make a difference to reported memory in the Task Manager. Now that we understand the issues of memory management, let’s explore the practicalities of measuring it and applying those measurements to a reallife application. 8.4 Designing for performance We stated at the outset that performance consisted of both good execution speed and a controllable memory footprint. We also said that design patterns could help us to achieve these goals. In this section, we’ll see how to measure memory footprint in real applications, and we’ll use a simple example to show how the use of design patterns can help us to understand the fluctuations in memory footprint that we may see in working code. Licensed to jonathan zheng 312 CHAPTER 8 Performance 8.4.1 Measuring memory footprint When we measured execution speed, we could do so either in JavaScript code using the Date object or with an external tool. JavaScript doesn’t provide any built-in capabilities to read