简体   繁体   English

与IE8慢的JavaScript

[英]Slow javascript with IE8

I'm developing a grid with excel-like functionality using the telerik controls. 我正在使用telerik控件开发一个具有类似excel功能的网格。 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. 用户可以使用Tab键移动到下一个单元格或使用向上/向下箭头键来获取上方或下方的单元格。 I've found the standard telerik grid is good but I've had to extend it with custom javascript to achieve what I need. 我发现标准的telerik网格很好,但我不得不用自定义的javascript扩展它来实现我的需要。

My problem is performance in the IE browser. 我的问题是在IE浏览器中的性能。 While Firefox, Chrome, Safari are all fine, IE is a real pain. 虽然Firefox,Chrome,Safari都很好,但IE真的很痛苦。 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. IE8比IE7要好得多,但是用光标键移动有点不自然,没有像Chrome或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. 由于网格的复杂性,我无法真正发布示例代码,但通常我会显示标准的telerik网格并使用telerik javascript API在浏览器中填充和绑定。 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. 当单击一个单元格时,javascript函数会将先前隐藏的输入控件从隐藏的集合移动到单元格中并使其聚焦。 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. 当您选中标签时,清除单元格值并使用ajax页面方法更新服务器,并以类似方式选择下一个单元格。

The grid has approx 40 columns and 20 rows, ie 800 extra controls are hidden on the page and only activated by clicking a cell or through navigating with the keyboard. 网格有大约40列和20行,即页面上隐藏了800个额外控件,只能通过单击单元格或通过键盘导航来激活。 I originally had just one hidden control for each column but moving up and down with the cursor keys became problematic in IE. 我原来每个列只有一个隐藏控件,但是使用光标键上下移动在IE中变得有问题。

Any advice for things to check that might speed up IE8 would be greatly appreciated. 任何有关检查可能加速IE8的事情的建议都将非常感激。

//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: 在IE8中加载页面,打开开发人员工具栏F12并打开分析:

Profiler (tab) > Start Profiling Profiler (tab)> 开始分析

Use your grid for a bit as normal, and let IE profile your code. 像往常一样使用你的网格,让IE浏览你的代码。

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 (eg 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. 它们可能是您无法控制的(例如,在Telerik的代码中)但是如果您添加的任何内容是功能的瓶颈,请回到此处以询问如何优化的建议。

It sounds as though most if not all of your controls related to the grid are created from within JavaScript? 听起来好像大多数(如果不是所有)与网格相关的控件都是在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 IE讨厌字符串连接:有很多关于它的性能不佳的帖子
  • 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不喜欢像你一样添加控件 - 所以尽可能重用它们
  • IE is faster if the controls are created via HTML (why oh why?) 如果通过HTML创建控件,IE会更快(为什么哦?为什么?)
  • IE hates it when you add lots of dynamic images and CSS with on-the-fly HTML controls 当您使用即时HTML控件添加大量动态图像和CSS时,IE会讨厌它
  • IE prefers innerHTML to addChild() (seems counter intuitive to string issue above) IE更喜欢innerHTML到addChild()(似乎与上面的字符串问题相反)
  • etc 等等
  • etc 等等

There's many more, but with IE you also have to implement almost every single JavaScript performance suggestion you can find: 还有更多,但使用IE,您还必须实现几乎所有可以找到的JavaScript性能建议:

  • 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) 来自像prototype和jQuery这样的框架的迭代器通常比传统的while和while循环慢(非常非常悲伤,但却非常真实)
  • 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. 当单击一个单元格时,javascript函数会将先前隐藏的输入控件从隐藏的集合移动到单元格中并使其聚焦。

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. 使用W3C DOM方法或表方法移动控件可能会降低IE速度,同时在其他浏览器中正常工作。

http://www.quirksmode.org/dom/innerhtml.html 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; this.moveFromTo = function(from,to){to.innerHTML = from.innerHTML; } }

Try Google Frame . 试试谷歌框架 It pushes the performance on IE8 ;) 它推动了IE8的性能;)

使用jslint.com测试代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM