Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 are 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);
}
like image 482
user189801 Avatar asked Oct 14 '09 12:10

user189801


2 Answers

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.

like image 69
scunliffe Avatar answered Oct 10 '22 18:10

scunliffe


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
like image 29
mimetnet Avatar answered Oct 10 '22 17:10

mimetnet