Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 动态更新数百万DOM元素样式的最快方法_Javascript_Jquery_Html_Css_Performance - Fatal编程技术网

Javascript 动态更新数百万DOM元素样式的最快方法

Javascript 动态更新数百万DOM元素样式的最快方法,javascript,jquery,html,css,performance,Javascript,Jquery,Html,Css,Performance,我使用DOM在浏览器中构建了康威的生活游戏。没什么特别的,以前做过。我的目标是尽可能地优化它。我的真实生活游戏代码运行良好,速度足够快,符合我的喜好。更新屏幕状态时出现瓶颈。由于屏幕上有几十万或数百万个DOM元素,您可以想象这可能非常缓慢(尽管比我最初想象的要快)。我的问题是: 一次在屏幕上处理超过一百万个DOM元素,迭代DOM元素列表并单独更改其样式的最快方法是什么? 我正在使用一个类来跟踪样式,动态更改它们的样式是否比类更好?我将所有这些元素都保存在一个多维数组中,通过另一种方式进行迭代会更

我使用DOM在浏览器中构建了康威的生活游戏。没什么特别的,以前做过。我的目标是尽可能地优化它。我的真实生活游戏代码运行良好,速度足够快,符合我的喜好。更新屏幕状态时出现瓶颈。由于屏幕上有几十万或数百万个DOM元素,您可以想象这可能非常缓慢(尽管比我最初想象的要快)。我的问题是:

一次在屏幕上处理超过一百万个DOM元素,迭代DOM元素列表并单独更改其样式的最快方法是什么?

我正在使用一个类来跟踪样式,动态更改它们的
样式
是否比
更好?我将所有这些元素都保存在一个多维数组中,通过另一种方式进行迭代会更好吗(循环本身不是瓶颈,我的代码中有很多这样的循环对我来说运行得足够快)?我真的不知道什么是“回流”,也不知道当元素改变时浏览器是如何呈现的。这些想法能否以提高性能的方式加以利用

这是我目前的代码:

var updateUI = function () {
    for (var i = 0; i < width; i++) {
        var row = grid[i];
        var rowUI = gridUI[i];
        for (var j = 0; j < height; j++) {
            rowUI[j].className = "b" + row[j];
        }
    }
}

不要更新每一个的样式。使用最通用的选择器,并操纵样式表中的实际样式规则。让浏览器完成剩下的工作。

您可以将网格划分为更小的区域,而不是仅更新被视为“脏”区域中的元素的样式(与上一次迭代相比,至少包含一个已更改的元素)。这将大大减少您在每次更新UI调用中需要执行的操作量,特别是当我们谈论数百万个元素时。

由于此问题被标记为jQuery,您可以使用它添加/删除所需的类。首先,获取在元素中使用的通用id/类,然后切换所需的类:

$('.generic-class').toggleClass('.another-class');
这样,您就可以将
。另一个类
添加到具有
。泛型类
的所有现有元素中

在css中:

.another-class { //other styles that you want to apply. }

如果您想要优化循环性能,您可以使用,因为您有大量的迭代。这是一种展开循环体的技术,因此每个迭代实际上完成了许多迭代的工作。杰夫·格林伯格(Jeff Greenberg)是达夫设备的第一个JavaScript端口。以下是算法:

//credit: Jeff Greenberg
var i = items.length % 8;

while(i){
    process(items[i--]);
}

i = Math.floor(items.length / 8);

while(i){
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
}

在500000次迭代时,执行时间比常规循环少70%。

DOM不擅长这类工作。我尖刻的回答是:不要,改用画布。我明白这一点,并且在参与这个项目时也知道:)我希望至少有一条“使用画布”的评论。在jsperf.com中设置比较测试以完成@MattDiamant!公平地说,浏览器正在做的工作,无论。。。但是你的观点是正确的。你能解释一下如何用我给出的代码实现这一点吗?在我的例子中,我似乎无法做到这一点。每个元素的样式都需要独立于所有其他元素。在任何情况下,我都不能一次操作多个。这是一个好主意,我已经计划实施一个版本。保留需要更新的个人的“更改列表”。使用jQuery非常慢。我的代码最初使用了
$('#g'+i+j)[0]来获取单元格,但是我通过缓存dom元素和使用普通javascript大大提高了性能。也许5年或10年前的JavaScript引擎从中受益,但现在我不确定它们是否受益。这是优化循环的一种很好的方法,我曾想过稍微放松一下循环,但正如我所提到的,我循环的方式并没有造成瓶颈。大部分工作是我应用风格的方式,这是我试图优化的。不过,我肯定会看到这样做是如何影响性能的。在500000次迭代中,当我在Chrome 31中运行它时,常规循环比任何“快速”达夫的设备测试用例都慢70%。是的,但在循环体中几乎什么都没有做。在真实的javascript代码中,很少有循环体如此琐碎的情况,以至于手动进行优化是有意义的。在OP的例子中,在循环体(字符串连接,DOM)中进行了大量的工作。真的吗?否决票?OP询问“我将所有这些元素保存在一个多维数组中,通过另一种方式进行迭代是否更好”这可能无法解决所有性能瓶颈,但这显然是解决该特定问题的一个更高效的解决方案。在500000-1000000次以上的迭代中,无论循环中的其他工作如何,您都应该始终使用这样的技术,我不敢相信您会试图与其他人争论。
//credit: Jeff Greenberg
var i = items.length % 8;

while(i){
    process(items[i--]);
}

i = Math.floor(items.length / 8);

while(i){
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
}