【发布时间】:2016-06-01 01:59:19
【问题描述】:
我目前正在开发基于JavaScript(pure js) 的游戏。游戏包含 5 个大型精灵表(例如 2861 × 768 和 4096 × 4864)。游戏开始时,所有 5 个精灵表都预加载到画布元素中。这 5 个精灵中的三个一起代表一个动画,其中每个精灵包含 75 帧。当一个精灵以动画结束时,我将其隐藏并显示下一个精灵。当第二个精灵完成动画时,我将其隐藏并显示第三个/最后一个。
当第二个或第三个精灵即将显示时,会发生 0.5 s - 1 s 的小延迟。图片正在解码。
这不是第一次发生的事情,而是总是发生的事情。并且该动画每 5 分钟重复一次,并且总是会出现小延迟。
我使用 canvas 元素进行预加载的原因是我认为 WebKit 会丢弃一段时间未使用的解码图像,并且 canvas 元素会阻止 WebKit 从内存中删除它。但这不起作用。
我已经尝试了几乎所有我知道的优化。我什至通过删除后代选择器等重构了我所有的 CSS。
我用来绘制这些动画的渲染器是我自己构建的,它运行良好,所以这不是问题,因为它在 Firefox 中运行良好。
编辑 [2016/03/04]: 我用画布做了一个模式,结果更糟。它滞后了很多。延迟保持不变。仅在 NW 中,该问题在 Chrome 中和 Firefox 中均不存在。
Codepen:我的渲染器http://codepen.io/anon/pen/JXPWXX
注意:如果我用opacity:0.2 而不是opacity:0 隐藏其他元素,则不会发生问题。但是,我不能那样隐藏它们,因为它们仍然可见。它们不应该是可见的。如果我添加 opacity:0.01 它是不可见的,并且问题不会在 Chrome 中发生,但在 NW 中仍然存在。
在 NW 中,当我从 opacity:0.2 切换到 opacity:1 时,正在处理图像解码。 Chrome 浏览器不会发生同样的事情。
我正在使用以下版本:
nw.js v0.12.3
io.js v1.2.0
Chromium 41.0.2272.76
commit hash: 591068b-b48a69e-27b6800-459755a-2bdc251-1764a45
三个图像精灵的大小分别为 14.4MB、14.9MB 和 15.5MB。每个精灵包含 75 帧。
为什么会发生这种情况,我该如何预防?
【问题讨论】:
-
请注意,这只发生在 Node Webkit 中。它在 Chrome 中运行良好。
-
你看过垃圾收集器吗?听起来垃圾收集器正在运行,这导致了暂停。无论是您处理画布的方式,还是您的渲染器产生的垃圾比您想象的要多。
-
你能分享一些代码或把它放在JsFiddle吗?
-
我同意@Bill 和@AndrewMyers。在可汗学院做了大量的原型设计,我最近发现在那里使用
image()方法时,GC 开销很大。不确定这是由于 Processing.js 库还是可汗学院沙箱的影响,但恢复到纯 JavaScript 后,在小型 100x100 像素putImage()操作上移除了大约 60MB/s 的 GC,并提供了 2-3 倍的性能提升。将有助于查看处理相关图像的代码部分。 -
@Darko Riđić 让我怀疑的一件事是第 89 行。
renderer.rAF = window.requestAnimationFrame(this.render.bind(this));绑定应该只做一次,提前。当你调用 bind 时,你正在创建一个新的东西......:D(无论是闭包还是函数的实际新实例,我对函数内部都不是很熟悉)。除非绝对必要,否则我不建议在任何类型的循环中这样做。
标签: javascript performance html5-canvas node-webkit large-files