Javascript / Jquery在循环中

时间:2016-02-01 21:26:08

标签: javascript jquery performance

我正在尝试在Javascript中编写一些图像过渡。

Page在这里:http://shineemc.com/trans/

(所有代码都在一个页面中,只是做一个“查看源”)

我的代码中有一部分非常慢。我尝试了几种不同的方式,但无论如何它都很慢。我做了一些日志记录,似乎是在第一次获取元素的位置时:

2016-02-01 15:54:28.386 (index):72 Setting BG position
2016-02-01 15:54:28.387 (index):83 In Each loop
2016-02-01 15:54:30.029 (index):85 Got div position
2016-02-01 15:54:31.148 (index):87 Set one BG
2016-02-01 15:54:31.148 (index):83 In Each loop
2016-02-01 15:54:31.171 (index):85 Got div position
2016-02-01 15:54:31.172 (index):87 Set one BG


console.log("Setting BG position");
$tiles.each(function() {
        console.log("In Each loop");
        var pos = $(this).position();
        console.log("Got div position");
        $(this).css( 'backgroundPosition', -pos.left +'px '+ -pos.top +'px' );
        console.log("Set one BG");
    });

如果查看日志时间戳,从第一次进入“每个”循环到它到达磁贴的第一个位置之间会有很大的延迟。 (~1.7秒)

我曾尝试将此作为for循环,认为“每个”通常是缓慢的自我,但行为仍在继续。

使用“for”循环:

2016-02-01 16:08:25.473 (index):72 Setting BG position
2016-02-01 16:08:25.474 (index):74 In For loop 1
2016-02-01 16:08:27.147 (index):77 Got div position
2016-02-01 16:08:28.299 (index):79 Set one BG
2016-02-01 16:08:28.300 (index):74 In For loop 2
2016-02-01 16:08:28.320 (index):77 Got div position
2016-02-01 16:08:28.321 (index):79 Set one BG


for (var i = 1; i < num_tiles; i++) {
        console.log("In For loop", i);
        var curTile = $('#tile'+i);
        var pos = curTile.position();
        console.log("Got div position");
        curTile.css( 'backgroundPosition', -pos.left +'px '+ -pos.top +'px' );
        console.log("Set one BG");
    }

我使用了ID而不是类选择器,从一个长字符串附加而不是让jQuery做36次...我没有想法......什么可能会减慢这些代码,我怎么能加快速度?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

看起来您正在强制同步布局,这会导致浏览器在循环的每次迭代中执行重新计算样式和布局。

尝试在一个批次中执行位置读取并在另一个批次中执行样式更新。

// Get array of all tile DOM elements
var tiles = Array.prototype.slice.call(document.querySelectorAll('.tile'));

// Read batch
var positionData = tiles.map(function (tile) {
    return {
        tile: tile,
        position: {
            left: tile.offsetLeft,
            top: tile.offsetTop
        }
    }
});

// Write batch
positionData.forEach(function (positionData) {
    var tile = positionData.tile;
    var position = positionData.position;

    tile.style.backgroundPosition = -position.left +'px '+ -position.top +'px';
}); 

此外,console.time('timerName');和console.timeEnd(&#39; timerName&#39;)是分析脚本执行时间的更好API。

答案 1 :(得分:1)

我不知道这是否是问题的真正原因,但我看到了关于表现的问题,我写了一些我读过here的内容。 就像那样,与jquery和raw js相比,DOM查询性能是:

vanilla - document.getElementById('test-table') => 12,137,211 (ops/sec)
jQuery - $('#test-table') => 350,557 (ops/sec)

即使这可能不是解决此问题的真正问题,但显而易见的是,它可以加速你的表现。我希望有所帮助。