如何加快IE8中innerHTML的读取速度?

Posted

技术标签:

【中文标题】如何加快IE8中innerHTML的读取速度?【英文标题】:How to speed up the reading of innerHTML in IE8? 【发布时间】:2011-01-25 06:13:07 【问题描述】:

我正在将 JQuery 与 DataTable 插件一起使用,现在我在下一行遇到了一个很大的性能问题。

aLocalData[jInner] = nTds[j].innerhtml; // jquery.dataTables.js:2220

我有一个 ajax 调用和 HTML 格式的结果字符串。我把它们转换成HTML节点,那部分就ok了。

var $result = $('<div/>').html(result).find("*:first");
// simlar to $result=$(result) but much more faster in Fx

然后我激活启用从普通表到可排序数据表的结果。速度在 Fx 中是可以接受的(900 行大约需要 4 秒),但在 IE8 中是不可接受的(超过 100 秒)。

我使用内置分析器对其进行了深入检查,发现上述单行占用了所有 99.9% 的时间,我该如何加快速度?我错过了什么?

            nTrs = oSettings.nTable.getElementsByTagName('tbody')[0].childNodes;
            for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
            
                if ( nTrs[i].nodeName == "TR" )
                
                    iThisIndex = oSettings.aoData.length;
                    oSettings.aoData.push( 
                        "nTr": nTrs[i],
                        "_iId": oSettings.iNextId++,
                        "_aData": [],
                        "_anHidden": [],
                        "_sRowStripe": ''
                     );

                    oSettings.aiDisplayMaster.push( iThisIndex );

                    aLocalData = oSettings.aoData[iThisIndex]._aData;
                    nTds = nTrs[i].childNodes;
                    jInner = 0;

                    for ( j=0, jLen=nTds.length ; j<jLen ; j++ )
                    
                        if ( nTds[j].nodeName == "TD" )
                        
                            aLocalData[jInner] = nTds[j].innerHTML; // jquery.dataTables.js:2220

                            jInner++;
                        
                    
                
            

【问题讨论】:

我不认为浏览器特别擅长处理 900 行的内容。在 Firefox 中,快速的 javascript 可以节省您的时间,但 IE 的脚本速度要慢得多。 我会使用某种分页机制吗,我们在 IE 中使用另一个网格控件时遇到了同样的问题,javascript 引擎的性能很糟糕,所以我们最终让用户能够对结果进行分页(或等待 IE)。 只是好奇,用var result = nTds[j].innerHTML; 替换行对性能有何影响? (暂时忘记它会破坏它) 我在 var temp 之前尝试过; (函数 MARK(nTd) temp=nTd.innerHTML; )(nTd[i]); aLocalData[jInner]=温度;并且 IE9 内置分析器显示标记所消耗的所有时间。 【参考方案1】:

尝试使用YUI DataTable。对于我扔它的任何大桌子来说,它都非常快。您可以毫无问题地将它与 JQuery 一起使用。

例如:http://paulisageek.com/compare/cpu/

【讨论】:

你有很棒的页面。我只是把链接给了几个朋友。在升级过程中会派上用场。 我有几张桌子,大小不一,在页面内看起来很正常。它们没有滚动条,但在滚动时保持标题可见。我正在使用带有 jquery-datatable 的 FixedHeader 插件。 yui-datatable 是否有相同的功能?例如datatables.net/release-datatables/extras/FixedHeader 当表格在屏幕内时,看起来很正常。当表格部分显示在屏幕上时,标题仍然可见。当表格在屏幕外时,不添加表头。 有些东西很接近,而且有点“HTML-ish”。只需使用 ScrollingDataTable 代替:developer.yahoo.com/yui/datatable/#scrolling。看直播developer.yahoo.com/yui/examples/datatable/dt_fixedscroll.html Tarjan,我看过例子,但不是我要的效果。 您的来电。我会选择现在可以使用的东西,然后再调整 UI。【参考方案2】:

我已经应用了自己的补丁,但仍在寻找真正的解决方案,它在 IE 中仍然很慢(10+ 秒)但可以接受。

我连续阅读一次 innerHTML 并拆分我自己的。

                    // For whom in interest
                    // Tested on IE8, Fx3.5
                    .....
                    aLocalData = oSettings.aoData[iThisIndex]._aData;
                    jInner = 0;
                    if(nTrs[i].getElementsByTagName('table').length == 0)
                        nTds =$.trim(nTrs[i].innerHTML).split(/<\/td>\s*/i);
                        for(j=0, jLen=nTds.length; j<jLen; j++)
                            aLocalData[jInner]=nTds[j].replace(/<td[\w\W]*?>/i,'');
                            jInner++;
                        
                        continue;
                    
                    nTds = nTrs[i].childNodes;
                    .....

如果有人知道为什么 innerHTML 很慢,请告诉我。

【讨论】:

【参考方案3】:

您是否考虑过为此使用 XML 数据岛?这有点棘手,但运行速度非常快。以下是如何将 HTML 表绑定到 XML 数据岛:

http://www.devx.com/tips/Tip/14109

(在岛上你可以从远程源加载数据,所以它就像 Ajax)。

【讨论】:

【参考方案4】:

10 列 900 行的表格将调用 innerHTML 函数 9000 次。而是将 innerHTML 内容附加到一个数组中,并且只在表格末尾调用一次 innerHTML。

类似:

var contentArray = ["","","单元格内容","",""]; container.innerHTML(contentArray.join(""));

这样,innerHTML 在表格构建过程中只被调用一次。如果不是,您可以在每行末尾调用 innerHTML,将调用 innerHTML 的次数减少到 900。

【讨论】:

代码来自jquery-datatable,它已经支持Html表和AJAX作为数据源。【参考方案5】:

我建议避免在 IE 中使用 innerHTML,并尝试使用 XML DOM 元素。我尝试了不同的循环修复,但延迟来自于提取 HTML 元素的值。问题在于 IE 的 javascript 引擎,需要变通才能获得可接受的性能。

经过多次试验和错误,我想出了对 innerHTML 的以下改进:

   var start = new Date().getTime()
     var resp=[];
     var dataTbl = $(data).find('#tbl').get(0);  // jquery Ajax call to html, .get(0) for real DOM
     var dataObj = dataTbl.rows;  
     for (var i = 1, l = dataObj.length; i < l; i++)  
     resp[i] =  
        label: dataObj[i].firstChild.firstChild.nodeValue,
        value: dataObj[i].lastChild.firstChild.nodeValue
      ;
    ;
  alert("On Array 5(DOM:For:array[index]:i++:): Milliseconds: " + ( new Date().getTime() - start) );

IE8 与 FireFox 3 的性能对比(非科学):将 2 列的表:1655 行报废到对象数组中

数组 1(JQuery .each):毫秒:20203 / 68 数组 2(用于:array.push):毫秒:19531 / 41 数组 3(while:array.push):毫秒:19609 / 44 数组 4(对于:数组 [索引]):毫秒:20562 / 326 数组 5(DOM:For:array[index]:i++:): 毫秒: 797 / 245 ***获胜者 数组 6(DOM:For:array[index]:i+=): 毫秒: 828 / 245 数组 7(DOM:For:array.push:i++): 毫秒: 797 / 250

【讨论】:

以上是关于如何加快IE8中innerHTML的读取速度?的主要内容,如果未能解决你的问题,请参考以下文章

使用多线程读取单个文件:应该加快速度吗?

索引如何加快搜索速度? [复制]

尝试使用javascript添加样式标签(IE8中的innerHTML)

Oracle 11g,如何加快“in”查询

java 读取大文件时怎么样才能加快速度?

在 IE8 中修改 <style> 元素的 innerHTML