向页面附加大量元素后出现延迟时间问题

时间:2011-09-09 06:45:19

标签: javascript

我正在网格上实现虚拟滚动。滚动/按需加载功能工作非常顺利。但是,当检测到用户正在快速滚动(定义为超过450毫秒)时,会在处理过程中显示带有加载gif的半透明div。

我的问题是,在加载完成并且附加完成后,我会调用隐藏覆盖层,期望看到更新的网格。相反,我有2-3秒的延迟,然后覆盖隐藏,数据显示。

问题:

A部分:为什么div仍然保留在屏幕上,即使隐藏它的代码行在追加后...导致意外的2-3秒等待,没有进度/加载指示器用户?

B部分:在完成并渲染dom的添加之前,可以采取哪些措施来确保叠加层保持可见?

执行的行如下:

    CheckToFetch(id, $(gridScrollElm).scrollTop(), true);
    ToggleOverlay(gridScrollElm, false);

正如您所看到的那样,理想情况下,叠加层应在加载和渲染数据后隐藏。

CheckToFetch后面有一系列方法调用,但我只会显示最相关的附加内容。

AppendData: function (id, data, firstTime)
{
    var gd = SGrid.GetGridData(id);
    var rowClass = (gd["RecordCount"] + 1) % 2; //sets us on correct course for adding AlternatingRow classes

    var grid = $('#' + id)
    var tbody = grid.children('tbody');

    var rowsToAdd = data["Records"];
    for (var r = 0; r < rowsToAdd.length; r++)
    {
        var elmsQueue = new Array(); //used to do efficient string concat, especially for IE
        elmsQueue.push('<tr>');
        for (var c = 0; c < gd['Columns'].length; c++)
        {
            elmsQueue.push('<td align="');
            elmsQueue.push(gd['Columns'][c]['DataAlign']);
            elmsQueue.push('" ');

            var id = rowsToAdd[r]["id"];
            var cell = rowsToAdd[r]["cell"];

            if (rowClass % 2 == 0)
            {
                elmsQueue.push('class="AlternatingRow">');
            }
            else
            {
                elmsQueue.push('>');
            }
            elmsQueue.push(cell[c]);
            elmsQueue.push('</td>');
        }
        elmsQueue.push('</tr>');
        tbody.append(elmsQueue.join(''));
        rowClass++;
    }

1 个答案:

答案 0 :(得分:1)

至于你的问题的 A部分,我只能假设,重绘操作(实际显示javascript操作结果的过程)可以独立于DOM操作和javascript执行运行。在您的代码中,您将多个元素附加到DOM,更新dom,向浏览器发出重排,但是(重排操作)不会将javascript执行保留。因此,如果重排持​​续一段时间,即使您还没有看到先前语句的结果,您最终会执行下一个javascript函数。

有几个资源涉及绘制事件和dom操作性能:http://www.html5rocks.com/en/tutorials/speed/html5/(查看优化策略部分),以及来自唯一的Paul Irish:{{3 }}

关于你问题的 B部分。如果我对A部分的假设是正确的,那么你唯一能做的就是确保将重绘操作限制在绝对最小值。为了实现这一目标,你应该暂时保留元素,直到你的全套准备好。 换句话说,继续收集新的&lt; tr&gt;数组(或字符串)中的元素,然后才进行tbody.append()。简单来说:将DOM操作移出循环

推迟实际的DOM修改这是一种常见的做法,也是推荐的使用脚本修改DOM的方法。

为了获得性能的每一点,您还可以尝试将实际对象(使用http://paulirish.com/2011/viewing-chromes-paint-cycle/创建)传递给append函数,而不是字符串,显然必须对其进行解析以获取列表你想要放在DOM中的元素。