【问题标题】:DOM manipulation slow in Chrome (hiding / showing elements)Chrome 中的 DOM 操作缓慢(隐藏/显示元素)
【发布时间】:2013-01-20 04:36:33
【问题描述】:

我今天早上在http://jsfiddle.net/Hwqb3/3/ 做了一个小测试。这是一个更大的分页项目的背后。我已经用原生 JS 和 jQuery 试过这个。测试使用jQuery。

在 SO 上的快速搜索表明,如果设置了 background-size,Chrome 的处理能力就会很差,但这里的情况并非如此。源中没有背景大小的痕迹,并且检查元素显示没有设置/继承背景大小。

在列表中添加 5,000 个元素时忽略初始页面加载。它只有几秒钟,但它只是为了测试一些元素。

在 Firefox 18.0.1 中,页面之间的移动几乎是即时的,而在 IE9 中,鼠标点击和分页结果刷新之间可能有 0.1 秒的延迟;但是,在 Chrome (24.0.1312.57 m) 中,延迟是明显的 1-2 秒。

昨晚我花了大部分时间在我的代码上倾注,看看我是否能在编写这个测试之前找到原因。这是赤裸裸的,仍然存在问题。

我只能假设 Chrome 正在处理 element.style.display='';不良。没有它(甚至循环遍历 5,000 个元素以显示='none'),事情就会变得活泼。

有什么想法吗?客户希望对大约 4,000 - 7,500 的结果集进行分页,但不希望重新加载页面,并且不明白他们应该应用过滤器将该列表缩减到

最后的手段是 AJAX 调用,这在 Chrome 上可能会稍微快一些。不过还没有经过测试。

提前致谢。

来自 jsfiddle 的代码,不包括 jQuery CDN 链接

HTML:

<a href="javascript:jump('first');">First</a>
<a href="javascript:jump('-1');">Previous</a>

<a href="javascript:jump('+1');">Next</a>
<a href="javascript:jump('last');">Last</a>
<br>
<ul id='list'>
</ul>

JS:

window.onload=function() { 
    window.list=$('#list'), window.max=20, window.page=0, window.pages=0, window.elements;

    var i=0;
    while(i<5000) {   
        i++;
        list.append("<li>"+i+"</li>");
    }

    jump('first');
};

function jump(operation) {

    window.elements=list.find('li');
    window.pages=Math.ceil(window.elements.length/window.max);

    if(operation=='first') {
        window.page=0;
    }
    else if(operation=='last') {
        window.page=(window.pages-1);
    }
    else if(operation=='+1') {
        window.page=(window.page+1);
        if(window.page>=window.pages) {
            window.page=(window.pages-1);
        }
    }
    else if(operation=='-1') {
        window.page=(window.page-1);
        if(window.page<0) {
            window.page=0;
        }
    }

    var showing=0, total=0;

    window.elements.each(function() {
        var show=false, self=$(this);

        if(showing<window.max) {
            if(total>=(window.page*window.max) && total<((window.page*window.max)+window.max)) {
                self[0].style.display='';
                showing++;
                show=true;
            }
        }

        if(!show) {
            self[0].style.display='none';
        }
        total++;
    });


}

【问题讨论】:

  • 在标签hrefjavascript:... 中使用javascript:... 的错误方式@ 标记a
  • 这是一个 20 分钟的测试用例代码,而不是真实/生产代码,以突出问题所在。否则我会包含一个 DOCTYPE 等。

标签: javascript google-chrome dom pagination


【解决方案1】:

检查一下

window.onload = function() { 
    window.list = $('#list'), 
    window.max = 20, 
    window.page = 0, 
    window.pages = 0, 
    window.elements;

    var i = 0;
    var html = '';
    while(i < 5000) { 
        i++
        html += '<li>' + i + '</li>';
    }    
    list.append(html);

    window.elements = list.find('li');
    window.pages = Math.ceil(window.elements.length/window.max);    

    jump('first');
};



function jump(operation) {

    if (operation == 'first') 
        window.page = 0;
    else if (operation == 'last') 
        window.page = window.pages - 1;
    else if (operation == '+1') 
        (window.page + 1 >= window.pages) ? window.page = window.pages - 1 : window.page++ ;
    else if (operation == '-1') 
        (window.page - 1 < 0) ? window.page = 0 : window.page--;

    var index = page * window.max;
    window.elements.hide().slice(index, index + window.max).show();
}

http://jsfiddle.net/Hwqb3/16/

【讨论】:

  • 您可以组合 2 个 :nth-child() 选择器,而不是为每个页面使用一个类:li:nth-child(n+5):nth-child(-n+10) jsfiddle.net/Hwqb3/6 使用 :nth-child() 不应阻止 jQuery 使用浏览器的 querySelectorAll() 函数,所以它也应该足够快。
  • 好吧,:nth-child():nth-child() 在列表末尾慢得要命:jsfiddle.net/Hwqb3/8
  • 其他问题,然后是添加新元素还是删除,nth-child 重新计算.. 这在长列表中可能也很慢
  • 虽然我知道我只问了特定于分页的问题,但分页结果(由于无刷新规则)也可以使用 javascript 过滤,因此分页的结果会发生变化(因此,通过$('#list &gt; li.match') 之类的东西查找元素。我想,我可以在每个过滤器之后重新计算页面并在页面中随机播放元素,如果我也选择类路由,我需要这样做;但是,类路由如果类为空,可能不会(不应该)影响 DOM。我回家后会看看。谢谢。
  • 您希望将另一个过滤器添加到页面过滤器并保留原始分页吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2015-09-24
  • 2018-09-14
  • 2023-03-22
  • 1970-01-01
相关资源
最近更新 更多