For example, adding 10000 items in a loop takes (on my computer):
Browser | Time |
---|---|
FireFox 3.5.6 | 205 ms |
Google Chrome 3.0.195.38 | 58 ms |
Internet Explorer 8.0.6001.18702 | 33375 ms |
The performance of IE8 is not acceptable, it's just too slow.
Fortunatelly there is a much faster method if you need to add many items when the ListBox is created (or it is possible to recreate the ListBox when it has to be repopulated).
The trick is to use the browser's native HTML parser to create the underlying SELECT and OPTION elements, which is much faster when creating many elements - even in IE. Calling DOM.setInnerHTML() is the easiest way to access this HTML parser, so a FastListBox implementation would look like:
public class FastListBox extends ListBox {
...
public FastListBox(List items)
{
super(createElement(items));
}
private static Element createElement(List items)
...
public FastListBox(List items)
{
super(createElement(items));
}
private static Element createElement(List items)
{
StringBuilder b = new StringBuilder();
b.append("<select>");
for (String item : items)
{
b.append("<option>");
b.append(item);
b.append("</option>");
}
b.append("</select>");
Element div = DOM.createDiv();
div.setInnerHTML(b.toString());
Element select = div.getFirstChildElement();
select.removeFromParent();
return select;
}
}
StringBuilder b = new StringBuilder();
b.append("<select>");
for (String item : items)
{
b.append("<option>");
b.append(item);
b.append("</option>");
}
b.append("</select>");
Element div = DOM.createDiv();
div.setInnerHTML(b.toString());
Element select = div.getFirstChildElement();
select.removeFromParent();
return select;
}
}
Browser | Time - using addItem() | Time - using FastListBox |
---|---|---|
FireFox 3.5.6 | 205 ms | 180 ms |
Google Chrome 3.0.195.38 | 58 ms | 42 ms |
Internet Explorer 8.0.6001.18702 | 33375 ms | 266 ms |
Resources:
- live demo (note: in IE it will probably freeze your browser for several seconds!)
- demo project (using the Google Plugin for Eclipse)
- source code of FastListBox
thanks a lot, you saved my day. I was already thinking of implementing an alternative to the combobox for IE
ReplyDelete