XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

The XSLDataGrid: XSLT Rocks Ajax
by Lindsey Simon | Pages: 1, 2, 3

XSLT On XHTML [1]

XSLT offers developers a mechanism for decorating the DOM that ensures well-formed markup and is both powerful and flexible. XSL transforms for UI widgets must be followed by a call to put the resultant XHTML back into the DOM being rendered. The XSLDataGrid uses its container's innerHTML property to do so (this is a technique known as AHAH [2]). It is worth noting here that many argue against using the proprietary, but well-supported, innerHTML property to populate the DOM. In an article entitled "Benchmark - W3C DOM vs. innerHTML", the ever-invalueable quirksmode.org has this to say about tables specifically:

The most obvious conclusion of these tests is that innerHTML is faster than "real" W3C DOM methods in all browsers. The W3C DOM table methods are slow to very slow, especially in Explorer.

More than once people said that creating elements only once and then cloning them when necessary leads to a dramatic performance improvement. These tests don't show anything of that kind. Although in most browsers cloning is minimally faster than creating, the difference between the two methods is small.

So what does the picture look like with XSLT for widget instantiation? The following diagram shows how the XSLDataGrid works.

Semantic Table
Semantic XHTML Table
+ XSLDataGrid.xsl = Decorated XHTML
More tags, attributes,
CSS, etc ...
+ Javascript
Instantiation,
event listeners,
etc ...
= Semantic Table
Rich DataGrid UI in Render Tree
and XML DOM in Dual-DOM in Memory

Dual-DOM, or, How I Dealt with innerHTML

There are essentially three ways to use the XSLDataGrid component:

  1. by fetching the transformed, fully decorated XHTML each time from the server
  2. by fetching semantic XHTML from the server and transforming it on the client
  3. by transforming XHTML already on the page in the client

In case 1, we don't really have to worry about keeping up with the DOM in the client, since we can farm off all the change operations (column resize, sort, and reorder) to the server, re-filling the container's innerHTML each time. Cases 2 and 3 are different, because we want to perform XSLT multiple times -- in other words, we will continue to need some valid XHTML on which we can perform XSLT. It's important to note that with innerHTML, what you put in is not necessarily what you get out when you read it. Internet Explorer, for instance, does some major "optimization" to the HTML, removing quotation marks, end tags, etc. Because we cannot quickly and reliably get well-formed XHTML from the container's innerHTML, when the XSLDataGrid initializes, it saves an XML DOM Document made from the original semantic XHTML in memory (aka Dual-DOM). It's also usually easier and more efficient to update this simpler XML DOM when we want to perform change operations than it would be to update the more complex, decorated DOM in the render tree. Let's take the example of resizing a column. Updating the DOM in the render tree would mean updating a great number of the DIVs, SPANs, THs, TDs, COLs etc., all the while taxing our client to render these changes as they're made. In the XML DOM, we change one width attribute's value and then re-run the XSLT. This approach allows us to do all of the "heavy lifting" in our XSLT engine -- get the presentation rules right once in XSL and then leverage it.

XSLT in the Browser

Internet Explorer and Firefox both offer exposed APIs for XSLT, and Manos Batsis has released a free software JavaScript library named Sarissa that wraps up the whole process of loading the XHTML and the XSL, and then calling the browser's native transform method. At the time of this writing, it appears that XSLT is not exposed to JavaScript in Safari or Konqueror. Support for Opera's XSLT API is not yet implemented in the XSLDataGrid.

Client-side sorting is done in the XSLDataGrid by first using DOM to strip out a subset of template nodes from the original XSL file. Then, the current TBODY content is transformed using this subset of the nodes along with a few param sets, and voila! Unfortunately, this sorting technique is limited to the datatypes recognized by XSLT 1.0, which are only "text" and "number." "date" would be pretty useful, and I suspect that I'll work on additional qname stylesheet templates to handle other sort cases in the coming weeks.

Benchmarks

Depending on the iterative nature of your transform or the development cycle in your product, it might make sense to offload the XSL transform to the client. To get a sense of how this performance scales with the XSLDataGrid, take a look at the following metrics table, which was created with some help from the Venkman profiler on my laptop. The server-side metrics are from a GNU/Linux machine with PHP 5.1.4. The client test machine is a 2GHz Pentium M running Mozilla Firefox 1.5.0.6.

Rows Pre-XSLT (kilobytes) Post-XSLT (kilobytes) Client-side XSLT (millisec.) Server-side XSLT (seconds)
200 17.5 29.6 156.25 .0306
500 43.6 68.8 369.79 .0356
1000 87.1 134 781.25 .0860
2000 179.1 270.5 1684.38 .2068
4000 363.1 543.5 3070.31 .3979
8000 731.1 1089.5 6265.63 .7861
20000 1885.1 2787.5 16695.31 4.088

Graph - XSLT in client

Conclusions

The greatest advantage to using XSLT for a JavaScript widget is the flexibility it provides for instantiation. Most Ajax-using web developers will be working with a server-side component/language, and having the option to reduce a client-side JavaScript decoration step to improve performance is nice, though it comes with a bandwidth price. In many projects, developers may be faced with a mixed bag: they may have a need for some large dynamic datagrids, which can only be originated on the server, as well as some smaller hand-coded tables, where a less-rich datagrid would be fine. For instance, developers might not always want to capture the fact that a user changed a column's size and store it as a preference, but even for these less-rich datagrids, developers do want them to look and feel the same. The XSLT approach gives the developer an opportunity to choose either a client- or server-based technique to achieve a similar result.

Pages: 1, 2, 3

Next Pagearrow