3

我有一个脚本需要 18 秒才能完成,因为它使用 HTML 数据填充了大约 300 个 DIV。下面的代码:

HTML:

    <div id="window">
        <div id="wall">
            <div class="module">
                <div>
                    <div class="face front"></div>
                    <div class="face back"></div>
                </div>
            </div>
        </div>
    </div>

Javascript:

for (i = 0; i < numModules-1; ++ i)
{
    var $mod = $('.module:eq(0)').clone();

    modLeft += modSize;
    if (modLeft + modSize > $('#wall').width())
    {
        modLeft = 0;
        modTop += modSize;
    }
    $mod.css({
        left: modLeft,
        top: modTop
    }).appendTo('#wall');
}

$.getJSON('html_server.php?callback=?', function(data) {
    var htmlCount = data.length;

    for (i = 0; i < numModules /* 300 or more */; ++ i)
    {
        var pick = Math.floor(Math.random() * Math.floor(htmlCount/2)) * 2;
        var contentFront = data[pick];
        var contentBack = data[pick+1];
        var modStyle = '';
        var $mod = $('.module:eq(' + i + ')');
        var $modFront = $mod.find('.front');
        var $modBack = $mod.find('.back');

        // Set HTML content on front & back of module
        $modFront.html(contentFront);
        $modBack.html(contentBack);
    }
});

如果我注释掉这两个.html()调用,运行时间会下降到大约 110 毫秒,所以这些显然是罪魁祸首。而且 HTML 内容不是很多,最多可能 300 字节的数据。

有什么建议吗?

编辑:添加了创建 DIV 的代码。也许我可以在 getJSON 回调中移动它,并在创建 HTML 时放入它们?那会有帮助吗?

4

3 回答 3

2

没有看到实际的标记很难判断,但应该看起来像:

$.getJSON('html_server.php?callback=?', function(data) {
    var mod='';
    for (i = 0; i < numModules /* 300 or more */; ++ i) {
        var pick = Math.floor(Math.random() * Math.floor(data.length/2)) * 2;
            mod += '<div class="module'>;
            mod += '<div class="front">'+data[pick]+'</div>');
            mod += '<div class="back">'+data[pick+1]+'</div>');
            mod += '</div>';
    }
    $('#someParent').html(mod);
});

在 JS 中构建所有内容,并且只插入一次 DOM 是这里的方法,但它必须根据实际标记构建,上面只是一个通用示例。

于 2012-04-11T17:58:42.710 回答
2

我创建module为模板并将内容替换为响应。并将您的 html 逻辑移到 JSON 下方,这样它就可以完成一次。见下文,

 var modTmpl = '<div class="module"><div><div class="face front">{CONTENT_FRONT}</div><div class="face back">{CONTENT_BACK}</div></div></div>';

$.getJSON('html_server.php?callback=?', function(data) {
    var htmlCount = data.length;

    var pick, tmp, $mods = [];
    for (i = 0; i < numModules /* 300 or more */; ++ i)
    {
        pick = Math.floor(Math.random() * Math.floor(htmlCount/2)) * 2;
        tmp = modTmpl
                .replace(/{CONTENT_FRONT}/, data[pick])
                .replace(/{CONTENT_BACK}/, data[pick+1]);
        $mods.push(tmp);
    }
});

/*
    I am leaving the below code untouched as it seems like you are 
    positioning each module. If not then you can just 
    $('#wall').append($mods.join('')); and remove below for loop
*/
for (i = 0; i < numModules-1; ++ i)
{
    var $mod = $mods[i]; //use the pushed modules and append now

    modLeft += modSize;
    if (modLeft + modSize > $('#wall').width())
    {
        modLeft = 0;
        modTop += modSize;
    }
    $mod.css({
        left: modLeft,
        top: modTop
    }).appendTo('#wall');
}
于 2012-04-11T18:24:07.140 回答
-1

我会在延迟值较小的设备上一次创建一堆(比如 20 个一组)setTimeout——它可能不会更快完成,但它不会在浏览器处理时锁定浏览器。因此,感知的启动速度可能会更快。您可以在加载时打开 AJAX 微调器或类似工具 - 并允许您的用户在渲染时立即进行交互。

于 2012-04-11T17:47:36.527 回答