加快JavaScript函数的速度,以改变构建的div元素的颜色';led显示屏'; 背景信息

加快JavaScript函数的速度,以改变构建的div元素的颜色';led显示屏'; 背景信息,javascript,html,css,performance,optimization,Javascript,Html,Css,Performance,Optimization,对于我正在进行的一个项目,我需要模拟一排可以以二进制显示不同数字的LED。使用大量边界半径为50%的div元素,我可以制作一行“led”。然后,JavaScript函数可以应用不同的css类来更改每个元素的颜色,以模拟其打开或关闭。我拥有的另一个功能是一个工具提示,当您将鼠标悬停在LED上时,它会显示LED显示的数值 问题 我遇到的问题是这种方法的性能。这是因为我的网页将使用几十行,每一行的值将在每次屏幕刷新时通过requestAnimationFrame()更新。目前,在我的笔记本电脑上更新页

对于我正在进行的一个项目,我需要模拟一排可以以二进制显示不同数字的LED。使用大量边界半径为50%的div元素,我可以制作一行“led”。然后,JavaScript函数可以应用不同的css类来更改每个元素的颜色,以模拟其打开或关闭。我拥有的另一个功能是一个工具提示,当您将鼠标悬停在LED上时,它会显示LED显示的数值

问题 我遇到的问题是这种方法的性能。这是因为我的网页将使用几十行,每一行的值将在每次屏幕刷新时通过
requestAnimationFrame()
更新。目前,在我的笔记本电脑上更新页面上每个LED行的实例大约需要5毫秒。这肯定低于我们在60Hz下每帧16.6ms的速度,但是在我的项目中,每帧都需要做一些其他的事情,这确实为这些工作留出了很少的时间

一个例子 我当前实现的一个示例可以在js fiddle上找到:。单击“基准”文本并检查控制台,查看更新LED行50000次所需的时间。你可以用它来快速评估你提出的任何想法的表现

注意:我每次都将显示设置为不同的值,以避免浏览器在检测到未发生实际更改时可能采取的任何巧妙手段。这些LED行的实际应用几乎每次都会给它们一个不同的值,因此这使得基准测试更加现实

我已经试着加速了 我在
led\u strips
对象中缓存了对led的引用,该对象提供了一个小的性能提升,因为浏览器不再需要每次执行
document.getElementById()

我听说在元素中添加/删除css类比直接使用JavaScript更改其css属性要快。这就是代码添加或删除类上的
以更改LED状态的原因

我发现,在尝试移除led div之前(反之亦然),首先检查led div是否启用了
类,这样可以提高性能

笔记 LED条没有固定的尺寸-其中LED的数量只能由其中包含的
LED
class div的数量决定

并非所有LED条带都会有工具提示-如果它们应该有工具提示,则容器div将启用
工具提示
类,并包含
工具提示内容
div

您将看到我注释掉了
display\u number\u on\u led
函数的一部分,该部分仅在工具提示可见时更新。此检查会大大提高性能,但意味着如果在更改条带后将鼠标悬停在条带上,工具提示可能会显示错误的值。这是不能接受的

浏览器更改显示的数字所花费的大部分时间似乎是在重新计算页面的布局/样式。避免这种情况肯定会提高性能,但我不确定如何做到这一点

总结
有人能找到一种方法来加速保留我目前拥有的功能的
在发光二极管上显示编号
功能吗?如果此方法无法更快地工作,是否有其他更快的方法(可能是画布?)

由于工具提示中未设置任何HTML,仅设置文本,因此可以使用
nodeValue
textContent
innertext
中的一种。在Chrome 66上,我的速度提高了50%以上,这似乎是最好的结果

运行原始代码(使用
innerHTML
)10次,我会:

50,000 iterations: 483.121826171875ms
50,000 iterations: 430.60400390625ms
50,000 iterations: 431.64599609375ms
50,000 iterations: 454.813232421875ms
50,000 iterations: 428.945068359375ms
50,000 iterations: 451.15673828125ms
50,000 iterations: 436.782958984375ms
50,000 iterations: 432.094970703125ms
50,000 iterations: 551.495849609375ms
50,000 iterations: 442.85400390625ms
使用工具提示。childNodes[0]。nodeValue=text

50,000 iterations: 212.26611328125ms
50,000 iterations: 198.85595703125ms
50,000 iterations: 206.324951171875ms
50,000 iterations: 201.528076171875ms
50,000 iterations: 202.0048828125ms
50,000 iterations: 195.52685546875ms
50,000 iterations: 207.598876953125ms
50,000 iterations: 202.48291015625ms
50,000 iterations: 207.677001953125ms
50,000 iterations: 197.98583984375ms
50,000 iterations: 259.39892578125ms
50,000 iterations: 221.156005859375ms
50,000 iterations: 238.042236328125ms
50,000 iterations: 212.44189453125ms
50,000 iterations: 221.1201171875ms
50,000 iterations: 225.68212890625ms
50,000 iterations: 226.552001953125ms
50,000 iterations: 209.56494140625ms
50,000 iterations: 215.00439453125ms
50,000 iterations: 222.412109375ms
50,000 iterations: 208.27099609375ms
50,000 iterations: 196.996826171875ms
50,000 iterations: 204.372802734375ms
50,000 iterations: 208.3291015625ms
50,000 iterations: 266.80810546875ms
50,000 iterations: 203.071044921875ms
50,000 iterations: 208.48876953125ms
50,000 iterations: 206.7939453125ms
50,000 iterations: 203.4111328125ms
50,000 iterations: 214.489013671875ms
使用
tooltip.textContent=text

50,000 iterations: 212.26611328125ms
50,000 iterations: 198.85595703125ms
50,000 iterations: 206.324951171875ms
50,000 iterations: 201.528076171875ms
50,000 iterations: 202.0048828125ms
50,000 iterations: 195.52685546875ms
50,000 iterations: 207.598876953125ms
50,000 iterations: 202.48291015625ms
50,000 iterations: 207.677001953125ms
50,000 iterations: 197.98583984375ms
50,000 iterations: 259.39892578125ms
50,000 iterations: 221.156005859375ms
50,000 iterations: 238.042236328125ms
50,000 iterations: 212.44189453125ms
50,000 iterations: 221.1201171875ms
50,000 iterations: 225.68212890625ms
50,000 iterations: 226.552001953125ms
50,000 iterations: 209.56494140625ms
50,000 iterations: 215.00439453125ms
50,000 iterations: 222.412109375ms
50,000 iterations: 208.27099609375ms
50,000 iterations: 196.996826171875ms
50,000 iterations: 204.372802734375ms
50,000 iterations: 208.3291015625ms
50,000 iterations: 266.80810546875ms
50,000 iterations: 203.071044921875ms
50,000 iterations: 208.48876953125ms
50,000 iterations: 206.7939453125ms
50,000 iterations: 203.4111328125ms
50,000 iterations: 214.489013671875ms
使用
tooltip.innerText=text

50,000 iterations: 212.26611328125ms
50,000 iterations: 198.85595703125ms
50,000 iterations: 206.324951171875ms
50,000 iterations: 201.528076171875ms
50,000 iterations: 202.0048828125ms
50,000 iterations: 195.52685546875ms
50,000 iterations: 207.598876953125ms
50,000 iterations: 202.48291015625ms
50,000 iterations: 207.677001953125ms
50,000 iterations: 197.98583984375ms
50,000 iterations: 259.39892578125ms
50,000 iterations: 221.156005859375ms
50,000 iterations: 238.042236328125ms
50,000 iterations: 212.44189453125ms
50,000 iterations: 221.1201171875ms
50,000 iterations: 225.68212890625ms
50,000 iterations: 226.552001953125ms
50,000 iterations: 209.56494140625ms
50,000 iterations: 215.00439453125ms
50,000 iterations: 222.412109375ms
50,000 iterations: 208.27099609375ms
50,000 iterations: 196.996826171875ms
50,000 iterations: 204.372802734375ms
50,000 iterations: 208.3291015625ms
50,000 iterations: 266.80810546875ms
50,000 iterations: 203.071044921875ms
50,000 iterations: 208.48876953125ms
50,000 iterations: 206.7939453125ms
50,000 iterations: 203.4111328125ms
50,000 iterations: 214.489013671875ms
编辑

除了上面提到的,您还可以做一些事情来稍微提高性能

1.

num_dec_digits
num_hex_digits
不会在迭代之间更改值,因为它们只取决于led的数量,因此可以在
get_led_references()中计算这些值。

function get_led_references(id) {
  var ref = document.getElementById(id);
  var has_tooltip = ref.children[0].className == "tooltip_content";
  var leds = Array.prototype.slice.call(ref.children);
  var references = {
    leds: leds,
    tooltip: has_tooltip ? leds.shift() : null
  };

  var log10_pow2 = Math.log10(Math.pow(2, leds.length));
  references.num_dec_digits = Math.ceil(log10_pow2);
  references.num_hex_digits = Math.ceil(log10_pow2 / Math.log10(16));

  return references;
}
当然,如果执行此操作,则必须相应地更改LED上的显示编号()

2.

get_padded_num()
函数中,您当前正在分配长度超过需要的新字符串。至少在您提供的示例数据中,在填充字符前面加上while循环的执行速度似乎要快10-20%:

function get_padded_num(number, length, base) {
  var str = number.toString(base);
  while (length > str.length) {
    str = '0' + str;
  }

  return str;
}
因此,通过添加修改,执行时间现在为:

50,000 iterations: 165.459716796875ms
50,000 iterations: 169.538818359375ms
50,000 iterations: 176.2109375ms
50,000 iterations: 170.885986328125ms
50,000 iterations: 167.305908203125ms
50,000 iterations: 169.608154296875ms
50,000 iterations: 168.797119140625ms
50,000 iterations: 175.070068359375ms
50,000 iterations: 165.182861328125ms
50,000 iterations: 169.580810546875ms

与您的问题相关的代码直接属于您的问题,而不仅仅是转储到外部站点。请先阅读,然后进行相应的编辑。(换言之太长了,读不下去了,可能是TL;已经有一些领域的博士学位了)这是一些不错的JS代码。您使用位运算符,缓存DOM元素,使用我甚至不知道的函数,如
String。重复
Number.toString
。。。我看不出你的代码有可能大幅提高速度。在我看来,这是最快的速度了。(仅供参考,在我的Chrome机器上,您的基准测试需要650到700毫秒)感谢您对代码的反馈。我怀疑可能没有什么改进的余地,但我不是专家,所以我问。至于我的问题的编辑,我应该在问题本身中包含一些关键的代码片段吗?我把它全部放在JSFIDLE上,因为我不想让问题太长。