【发布时间】:2018-07-20 11:29:16
【问题描述】:
背景资料
对于我正在进行的项目,我需要模拟一排可以显示不同二进制数字的 LED。使用border-radius: 50% 的大量 div 元素,我可以制作成行的“LED”。然后,JavaScript 函数可以应用不同的 css 类来更改每个元素的颜色,以模拟它是打开还是关闭。我拥有的另一个功能是工具提示,当您将鼠标悬停在 LED 上时,它会显示 LED 显示的数值。
问题
我遇到的问题是这种方法的性能。这是因为我的网页将使用几十个这样的行,并且每行都会通过requestAnimationFrame() 在每次屏幕刷新时更新其值。目前,在我的笔记本电脑上更新页面上 LED 行的每个实例大约需要 5 毫秒。这绝对低于我们在 60Hz 时每帧的 16.6 毫秒 - 但是对于我的项目,每帧还需要完成许多其他事情,这确实为这些事情留下了很少的时间。
一个例子
我当前的实现示例可在此处的 js fiddle 上找到:https://jsfiddle.net/dL6jq7or/25/。单击“基准”文本并检查控制台以查看将 LED 行更新 50,000 次所需的时间。您可以使用它来快速评估您提出的任何想法的性能。
注意:我每次都将显示设置为不同的值,以避免浏览器在检测到没有发生实际更改时可能会采取的任何巧妙技巧。这些 LED 行的实际应用几乎总是每次都给它们一个不同的值,因此这使得基准更加现实。
我已经尝试过加快速度
我在 led_strips 对象中缓存了对 LED 的引用,这提高了性能,因为浏览器不再需要每次都执行 document.getElementById()。
我听说在元素中添加/删除 css 类比直接使用 JavaScript 更改其 css 属性要快。这就是代码添加或删除 on 类以更改 LED 状态的原因。
我发现首先检查 led div 是否具有 on 类,然后再尝试将其删除(反之亦然),这会提高性能。
注意事项
LED 灯条没有固定大小 - 其中的 LED 数量应仅由其中包含的 led 类 div 的数量决定。
并非所有 LED 灯条都有工具提示 - 如果它们应该有一个工具提示,那么容器 div 将具有 tooltip-enabled 类并包含一个 tooltip-content div。
您会看到我注释掉了 display_number_on_leds 函数的一部分,该部分仅在工具提示可见时才更新。此检查提供了很大的性能提升,但意味着如果您在更改后将鼠标悬停在条上,工具提示可能会显示错误的值。这是不可接受的。
浏览器更改显示数字所花费的大部分时间似乎是重新计算页面的布局/样式。避免这种情况肯定会提高性能,但我不知道该怎么做。
总结
任何人都可以找到一种方法来加速 display_number_on_leds 函数,以保留我目前拥有的功能吗?如果这种方法不可能更快地工作,是否有任何替代方法可以更快(可能是画布?)。
【问题讨论】:
-
与您的问题相关的代码直接属于您的问题,而不仅仅是转储在外部站点上。请阅读How to Ask 和minimal reproducible example,然后进行相应的编辑。 (作为交换,其余的解释可能会减少一点,这可能是 TL;对于某些人来说已经是 DR 领域了。)
-
这是一些不错的 JS 代码。您使用按位运算符,缓存 DOM 元素,使用我什至不知道的函数,例如
String.repeat或Number.toString... 我认为您的代码没有显着提高速度的可能性。 IMO 它几乎是尽可能快的。 (仅供参考,您的基准测试在我的 Chrome 机器上需要 650 到 700 毫秒) -
感谢您对代码的反馈。我怀疑可能没有什么改进的余地,但我不是专家,所以我问了。
-
至于我的问题的编辑,我是否应该在问题本身中包含一些关键的sn-ps代码?我把它全部放在 jsfiddle 上,因为我不想让问题太长。
标签: javascript html css performance optimization