Slow javascript with IE8
I'm developing a grid with excel-like functionality using the telerik controls. For example users can click on a cell and the cell turns into an input control for editing. Users can tab to move onto the next cell or use arrow keys for up/down to get the cell above or below. I've found the standard telerik grid is good but I've had to extend it with custom javascript to achieve what I need.
My problem is performance in the IE browser. While Firefox, Chrome, Safari are all fine, IE is a real pain. IE8 is considerably better than IE7 however moving around with the cursor keys is a bit unnatural, and nothing like as smooth as Chrome or FF.
I can't really post sample code due to the complexity of what the grid is doing, but generally I'm displaying the standard telerik grid and using the telerik javascript API to fill and bind in the browser. When a cell is clicked a javascript function moves a previously hidden input control into the cell from a hidden collection and gives it focus. When you tab away the cell value is cleared and the server is updated using ajax pagemethods and the next cell is selected in a similar manner.
The grid has approx 40 columns and 20 rows, i.e. 800 extra controls 开发者_如何学Care hidden on the page and only activated by clicking a cell or through navigating with the keyboard. I originally had just one hidden control for each column but moving up and down with the cursor keys became problematic in IE.
Any advice for things to check that might speed up IE8 would be greatly appreciated.
//selects a cell and sets the value
this.select = function(value) {
this.moveFromTo(this._hiddenCell, this._gridCell);
this._bIsSelected = true;
this.set_inputValue(value);
this._focus();
}
//clears inner content for a cell
this.removeChildrenFromNode = function(node) {
if (node == undefined || node == null) {
return;
}
var len = node.childNodes.length;
while (node.hasChildNodes()) {
node.removeChild(node.firstChild);
}
}
//move back or forwards between hidden or active cell
this.moveFromTo = function(from, to) {
var currChild = null;
this.removeChildrenFromNode(to);
var i = 0;
if (from.childNodes != null) {
while (i < from.childNodes.length) {
currChild = from.childNodes[i];
if (to != null) to.appendChild(currChild);
i += 1;
}
}
this.removeChildrenFromNode(from);
}
Load up your page in IE8, open the developer toolbar F12 and turn on the profiling:
Profiler (tab) > Start Profiling
Use your grid for a bit as normal, and let IE profile your code.
When done, click Stop Profiling, and verify which function calls are chewing up the memory or taking the most time.
They may be ones that are beyond your control (e.g. in Telerik's code) but if anything you've added is the bottleneck post the function(s) back here on SO to ask for advise on how to optimize.
It sounds as though most if not all of your controls related to the grid are created from within JavaScript?
If so there are a couple of things to keep in mind:
- IE hates string concatenation: there are numerous posts about it's poor performance
- Ensure your clearing your events when switching controls and not just overwriting them
- memory leaks are not your friend
- IE hates adding controls as much as you do - so reuse them when possible
- IE is faster if the controls are created via HTML (why oh why?)
- IE hates it when you add lots of dynamic images and CSS with on-the-fly HTML controls
- IE prefers innerHTML to addChild() (seems counter intuitive to string issue above)
- etc
- etc
There's many more, but with IE you also have to implement almost every single JavaScript performance suggestion you can find:
- short variable names
- ensure variables are properly scoped (otherwise the runtime will jump up scopes until nothing is left to search)
- iterators from frameworks like prototype and jQuery are often slower than traditional for and while loops (VERY VERY sad but quite true)
- etc
- etc
When a cell is clicked a javascript function moves a previously hidden input control into the cell from a hidden collection and gives it focus.
You have to explain the quote above in more detail. How exactly do you move the previously hidden control into the cell? Check the site below for a benchmark that uses different methods to generate a dynamic table. Moving the control using the W3C DOM methods or table methods could slow down IE while working fine in other browsers.
http://www.quirksmode.org/dom/innerhtml.html
Edit: Try this to check if it's faster(not as a final solution):
this.moveFromTo = function(from, to) { to.innerHTML = from.innerHTML; }
Here are some useful links
Understanding and Solving Internet Explorer Leak Patterns
IE Sieve, Memory Leak detector for Internet Explorer
JavaScript Profiling
Try Google Frame. It pushes the performance on IE8 ;)
Test you code with jslint.com
精彩评论