NW/Node Webkit - 图像解码,即使它已经可见

NW/Node Webkit - Image decodes even if it is already visible

我目前正在开发一款基于 JavaScript(pure js) 的游戏。游戏包含 5 个大精灵表(例如 2861 × 768 和 4096 × 4864)。游戏开始时,所有 5 个精灵表都预加载到 canvas 个元素。这 5 个精灵中的三个代表一个动画,其中每个精灵包含 75 帧。当一个精灵以其动画结束时,我将其隐藏并显示下一个精灵。当第二个精灵完成动画时,我将其隐藏并显示 third/last 一个。

当第二个或第三个精灵即将显示时,会发生0.5 s - 1 s的小延迟。图片正在解码中。

这不是第一次发生的事情,而是经常发生的事情。那个动画每 5 分钟重复一次,小延迟总是发生。

我使用 canvas 元素进行预加载的原因是我认为 WebKit 会在一段时间内丢弃未使用的解码图像,并且 canvas 元素会阻止 WebKit 删除它从记忆中。但那是行不通的。

我几乎尝试了所有我知道的优化。我什至通过删除后代选择器等重构了我所有的 CSS

我用来绘制这些动画的渲染器是我自己构建的,它运行良好,所以这不是问题,因为它在 Firefox 中运行良好。

编辑 [2016/03/04]: 我用 canvas 做了一个模式,结果更糟。它滞后了很多。延迟保持不变。仅在 NW 中,问题在 Chrome 和 Firefox 中都不会存在。

Canvas 模式 - 滞后:

默认(HTML)模式 - 完美运行:

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 帧。

为什么会发生这种情况,我该如何预防?

我建议使用 idata = ctx.getImageData(0, 0, canvas.width, canvas.height) 从画布中检索数据数组,然后 ctx.putImageData(idata, 0, 0) 在精灵之间切换,而不是隐藏画布。

鉴于让 Webkit 认为图像仍然显示会使问题消失(如您的不透明度实验所示),我将它几乎完全移出可见区域,只有一个透明行与视口重叠(使用溢出隐藏)。

请注意,未打包的 4000x4000 精灵 sheet 将使用 64 兆字节的 RAM(每个像素 4 字节 (=RGBA)),因此确保下一张图像获得 "warmed up" 提前一点,不让所有的人一直解压?

尝试直接切换到google-chrome,因为新的nw 版本可能是19.04.2016 发布的。在那之后,NW 将有望跟上每个 Chromium 版本的发布。

你应该不会在 Chrome 中遇到同样的问题。