javascript - 如何在不重新加载的情况下重新启动 Canvas

标签 javascript canvas meteor three.js webgl

我只是想在网站上重新启动 Canvas 。我不想重新加载页面,所以重新启动必须动态完成。问题:重启几次后动画变慢,内存增加。

实际上我面临更复杂的情况:我使用 javascript 框架加载页面,MeteorJS 和 IronRouter。更改 URL 只会更改 DOM(节点被删除)但“页面”并没有真正留下。所以我认为使用 Canvas 返回我的页面可以被同化为动态 Canvas 重启,因为我也没有解决方案。

这就是为什么我从两个 Angular 描述问题(两者都是同一个问题):

  1. 首先是一个简单的页面,其中有一个按钮要求 Canvas 重新启动
  2. 然后使用 IronRouter 将解决方案应用于 MeteorJS,并尝试多次返回我的页面。

注意:我的 Canvas 内容是一些 WebGL(在 ThreeJS 中)。


<强>1。动态删除和重新初始化 Canvas 。

在这种情况下,我面临这两个问题:

  • 动画不流畅
  • 内存增加。准确地说:

Memory use
(来源:hostingpics.net)

  1. 页面已加载,使用 Canvas /2. 重新启动 Canvas 30-40 次(我没有停止重新启动,所以我不知道为什么增加不是线性的)/3. 使用 Canvas /4. 关闭选项卡(重新加载页面只会释放一小部分已调动的内容)

关于 SO 的问题很少询问如何解决这些问题,但复制解决方案可以部分解决问题。我已经阅读了两个主要内容:

  • 必须从 DOM 中清除与 Canvas 相关的部分(节点、变量、函数)(这是 Meteor 所做的事情。但在第一部分中它仍然相关,但不足以防止出现问题)。<
  • 如果 requestAnimationFrame 已被调用,它需要分配给一个变量,以便 cancelAnimationFrame(variable) 可以停止它。这确实似乎可以防止帧速率下降。虽然内存力很高,但至少 Action 仍然很流畅。

使用这些解决方案,内存问题仍然会发生。

这是一个例子:http://codepen.io/Astrak/pen/RNYLxd


<强>2。在 MeteorJS 中:我无法得到这个部分解决方案。

这是我在我的应用程序中写的,id=requestAnimationFrame(myAnimation) 声明为全局:

 Template.myTemplate.destroyed=function(){
      cancelAnimationFrame(id);
      document.body.removeChild(document.querySelector('canvas'));//useful in Meteor ?
 };

尽管有这些说明,我的动画在 MeteorJS 中比在前面的例子中变慢得多:它在 3-4 页面更改后变得不可用。同样的内存问题。

感谢您的每条评论和回答以及愉快的编码:)


相关问题:

Performance drop on multiple restart of scene from threejs

Performance drops when trying to reset whole scene with Three.js

How do we handle webgl context lost event in Three.js

Pause, resume and restart Canvas animations with JS

How can I restart my function?

JavaScript restart canvas script

最佳答案

对于内存问题,我推荐 Chrome 的 javascript profiler - 你可以比较 Canvas 重新加载前后的快照,看看哪些对象没有从内存中释放。

问题通常来自事件处理程序和/或使用闭包。例如,如果您将一个函数挂接到 window 对象的 onresize 事件,则只要 window 存在,该函数中引用的所有对象都将保留在内存中。因此,如果您想在不实际刷新浏览器 session 的情况下刷新页面内容,请始终从全局对象中删除事件处理程序。

类似于闭包。它们将在函数范围和引用变量之间创建链接,以防止 GC 收集它们。检查这个https://www.meteor.com/blog/2013/08/13/an-interesting-kind-of-javascript-memory-leak

关于javascript - 如何在不重新加载的情况下重新启动 Canvas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28930265/

相关文章:

Javascript:将值传递给具有数组属性的函数

javascript - 在javascript中选择第一个div child 的第二个 child

javascript - 1 秒后隐藏 Canvas ctx.rect() - Javascript

canvas - 创建一个在每个缩放级别上重新绘制的网格

javascript - Angular 单元测试 : Browser is not defined?

javascript - 从 ng-change 获取文件

javascript - Rails、Canvas 和 Javascript - 将图像从 Flickr 转换为灰度

javascript - Materialize 导航栏在 Meteor 中不起作用

javascript - 无法在 Handlebars 内填充字段 if 语句

javascript - 获取 Meteor 0.9.1.1 点击事件来更新对象