PDA

View Full Version : Render Optimization by using DOM Elements



iterator
18 Feb 2009, 9:28 AM
I want to suggest a render improvement.

I took a look in the source code of GXT and found snippets like this one from com.extjs.gxt.ui.client.widget.grid.GridView.doRender()


cb.append("<td class=\"x-grid3-col x-grid3-cell x-grid3-td-" + c.id + " " + css
+ "\" style=\"" + c.style + "\" tabIndex=0 " + cellAttr
+ "><div class=\"x-grid3-cell-inner x-grid3-col-" + c.id + "\" " + attr + ">" + rv
+ "</div></td>");The HTML string that are created that way lack escaping for the values (rv in this case) and must be parsed by the browser's HTML parser. Why not creating and appending DOM elements directly. This would certainly be more efficent and also look better in the code. With normal GWT technics it could look like this:



SpanElement span = SpanElement.as(DOM.createSpan());
span.appendChild(Document.get().createTextNode(value.toString()));
span.getStyle().setProperty("color", color);

DivElement div = DivElement.as(DOM.createDiv());
div.appendChild(span);

// finally append the structure to the document somewhere
someElement.appendChild(div);
Thus parsing is no more needed since DOM structures are created and passed directly. This is better understandable when reading code and even faster when running. By the way escaping of text content is done also by this approach. The current GridView would render values like "4 < 5" without any escaping. The DOM would be corrupted by this.

In consequence the known GridCellRenderer interface for example could then return a DOM Element instead of the lowlevel string and thus look like this:


public interface GridCellRenderer<M extends ModelData> {
public Element render(M model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<M> store);
}I like to suggest that everywhere where possible but at least at the performance critical places like Grids to move from String concatenation to higherlevel DOM manipulation.

micgala
26 Feb 2009, 2:55 AM
Hi.

I agree strongly with you.
Implementing such modifications to the source code of GXT would bring a good gain in performance, specially for grids rendering. I know that recently we have already got a gain in that direction, but the proposed suggestion would be even better.

It would be nice if GXT developers would take a look into this direction.

Best regards,
Michel.

jpnet
26 Feb 2009, 11:51 AM
I also agree and support this.

Can we get a response from the GXT team? What are your thoughts on this?

-JP

iterator
27 Feb 2009, 2:36 AM
I have a litte update to my suggestion:


public interface GridCellRenderer<M extends ModelData> {
public Element render(M model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<M> store);
}

should be:


public interface GridCellRenderer<M extends ModelData> {
public Node render(M model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<M> store);
}

Because by doing this Elements and Text instances could be passed.

Kango_V
2 Mar 2009, 9:58 AM
A very good idea. Well done that man :)

micgala
12 Mar 2009, 4:56 AM
I didn't want this to become a dead idea....

Is anyone from gxt team looking into this?
Just a "I read this" would be nice...

sraubal
16 Mar 2009, 8:02 AM
Hi,

I wonder if the way you suggest to do it really enhances performance in all browsers - especially IE.
I remember times when using innerHTML was way faster than creating and appending DOM nodes.

Does anybody know some numbers about that for the current versions (IE 6, IE 7, IE 8beta) vs. other browsers like Firefox, Safari...?

Regards,
Stefan

amalter
21 Mar 2009, 10:19 AM
Hi,

Just wondering if you have any benchmarks for this.

Last that I compared was with FF 2.x and IE 6. I found that setting innerHtml to be about 6-8x faster than DOM creation. I agree that the code looks cleaner, but, I'd really need to see some numbers to be convinced that your approach is 'faster'.

-Adam Malter

iterator
22 Mar 2009, 11:42 AM
I made a benchmark test with a little example that creates a table containing 1000x10 cells. One version used StringBuilder and setInnerHTML and the other one used DOM manipulation.

The results are:

IE 7:
StringBuilder+setInnerHTML: 547ms
DOM Manipulation: 1203ms

FF 3:
StringBuilder+setInnerHTML: 91ms
DOM Manipulation: 364ms

This is a clear result and I must admit that I was sure that direct manipulation should be a lot faster than string concatenation and parsing. But benchmarks show clearly that this is not true. I really wonder why it is that way. Sorry for claiming the performance gain but it looked so promising. Also it would have been a good structural improvement.

brendand
21 Apr 2009, 3:27 PM
Check out http://www.quirksmode.org/dom/innerhtml.html
You can run the tests in your current browser to compare which method is faster.

It may seems counter-intuitive at first why innerhtml is faster, but if you think about it, that's what browsers do, take a string of html, parse it really quick and display it.

I've been working on a large RIA that is all javascript on client, and we always use what they call the "innerhtml 2" method for rendering.

Perhaps you could investigate which is faster.

Current:

cb.append("<td class=\"x-grid3-col x-grid3-cell x-grid3-td-" + c.id + " " + css
+ "\" style=\"" + c.style + "\" tabIndex=0 " + cellAttr
+ "><div class=\"x-grid3-cell-inner x-grid3-col-" + c.id + "\" " + attr + ">" + rv
+ "</div></td>");

cb.append("<td class=\"x-grid3-col x-grid3-cell x-grid3-td-");
cb.append("c.id);
cb.append(" ");
cb.append(css);
cb.append("\" style=\"");
cb.append(c.style);
cb.append("\" tabIndex=0 ");
cb.append(cellAttr);
cb.append("><div class=\"x-grid3-cell-inner x-grid3-col-");
cb.append(c.id);
cb.append("\" ");
cb.append(attr);
cb.append(">");
cb.append(rv);
cb.append("</div></td>");

monzonj
22 Apr 2009, 6:13 AM
I just wanted to say that innerHTML is not faster than W3C DOM 2 in the newest Safari (version 4). You can perfectly do the test in that browser with the http://www.quirksmode.org/dom/innerhtml.html test

Iterator, could you run your test in Safari 4 beta and test?

I think in the future, innerHTML will be out of fashion. But we are not near to see it dissapear, other new browsers like Chrome 2 (in beta now) and FF 3.1 (also beta) are much faster with innerHTML than with DOM.

I really like Safari, is the best browser out there, not to mention is the only one that gets a 100 in the acid test http://acid3.acidtests.org/
I hope chrome copies safari soon, after all they both use webkit.

iterator
22 Apr 2009, 10:49 PM
In the meanwhile I see that there would be a big gain by having DOM manipulation instead of string concatenation because if one creates DOM element the sinking of events would be possible without registering global javascript function. The current solution breaks the Java approach of GWT. If I use custom rendering today I stand with one foot outside of the GWT approach. What if there will be a GWT solution for the Desktop? GWT design seems well prepared for that. Imagine: You write one application and it runs in Web and also standalon in a JVM.

I am looking forward to the days where DOM manipulation is faster which should be normal. Because the browser internally must also create the DOM structure after parsing. So it is contra intuitive for me that almost all browser are slower if something is passed that is structural better prepared. Probably a lot of events are fired when nodes are appended to a structure that is prepared. But this could be omitted when there is not yet a connection to the document itself. I think something like this is done internally by the browser when it creates DOM structures from string. This should be usable from Javascript too.

BTW: C++ is faster than Java but in almost all cases I would choose Java because its structural benefits wheight more for me. Time can sometimes be saved by a better design that is supported by system and not only by its raw performance.

Probably GXT could support both ways. Why not? In most cases there are is not so many rendered data that the performance is limiting the user experience.