如何重新启动画布而不重新加载

时间:2015-03-08 18:30:45

标签: javascript canvas meteor three.js webgl

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

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

这就是我从两个角度描述问题的原因(两者都有同样的问题):

  1. 首先是一个简单的页面,其中一个按钮要求画布重新启动
  2. 然后将解决方案应用于使用IronRouter的MeteorJS,并尝试多次返回我的页面。
  3. 注意:我的画布内容是一些WebGL(在ThreeJS中)。


    1。动态删除和重新初始化画布。

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

    • 动画不顺畅
    • 内存增加。确切地说:

    Memory use http://img15.hostingpics.net/pics/263473issue.png 1.页面加载,玩帆布/ 2.重新启动画布30-40次(我没有停止重启,所以我不知道为什么增加不是线性的)/ 3.使用画布/ 4.关闭标签(重新加载)该页面只释放了动员的一小部分)

    关于SO的几个问题尚未询问如何解决这些问题,但复制解决方案部分解决了这个问题。我读过两件主要的事情:

    • 必须从DOM中清除与画布相关的部分(节点,变量,函数)(这是Meteor所做的。但在第一部分中它保持相关性,但还不足以防止这些问题)。
    • 如果调用了requestAnimationFrame,则需要将其分配给变量,以便cancelAnimationFrame(variable)可以阻止它。这确实似乎可以防止帧率下降。虽然记忆力很高,但至少动作仍然流畅。

    通过这些解决方案,内存问题仍然存在。

    以下是一个示例:http://codepen.io/Astrak/pen/RNYLxd


    2。在MeteorJS中:我无法使这个部分解决方案有效。

    以下是我在我的应用中写的内容,id=requestAnimationFrame(myAnimation)声明为globaly:

     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

1 个答案:

答案 0 :(得分:1)

对于内存问题,我建议使用Chrome的javascript探查器 - 您可以在重新加载画布之前和之后比较快照,并查看哪些对象未从内存中释放。

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

与闭包相似。它们将在函数的作用域和引用的变量之间建立链接,阻止GC收集它们。请检查此https://www.meteor.com/blog/2013/08/13/an-interesting-kind-of-javascript-memory-leak

相关问题