Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 动态注入画布上的意外性能损失_Javascript_Jquery_Ajax_Performance_Canvas - Fatal编程技术网

Javascript 动态注入画布上的意外性能损失

Javascript 动态注入画布上的意外性能损失,javascript,jquery,ajax,performance,canvas,Javascript,Jquery,Ajax,Performance,Canvas,我正在处理一个小项目,但我遇到了一个奇怪的错误(?)使用Ajax将画布注入页面(更具体地说,是jQuery$('element').load('some_file.html')方法,它只是将文件的html/文本附加到指定的元素中) 我有两个做不同事情的“模块”。第一个是我的问题,是一个简单的画布,有大约2000个粒子随机移动。 该结构如预期的那样工作,我可以在两个模块之间切换,并且DOM将被更新,而无需刷新页面 问题是,如果我在两个项目之间来回切换,第一个模块上画布的性能就会下降 这种行为对我来

我正在处理一个小项目,但我遇到了一个奇怪的错误(?)使用Ajax将画布注入页面(更具体地说,是jQuery$('element').load('some_file.html')方法,它只是将文件的html/文本附加到指定的元素中)

我有两个做不同事情的“模块”。第一个是我的问题,是一个简单的画布,有大约2000个粒子随机移动。 该结构如预期的那样工作,我可以在两个模块之间切换,并且DOM将被更新,而无需刷新页面

问题是,如果我在两个项目之间来回切换,第一个模块上画布的性能就会下降

这种行为对我来说是意外的,但是如果我错了,请告诉我:加载包含canvas标记的模板时,将创建一个新的canvas元素,并且应该替换指向旧canvas和旧粒子数组的指针

我测试了我的旧画布循环是否仍在后台运行,但看起来不是这样。我还尝试禁用ajax缓存,并对粒子属性的范围进行了一些测试,但没有任何更改,即使使用全局变量也是如此。 我还试图取消requestAnimationFrame,但没有成功

如果我不够精确,我很抱歉,这里有一个JSFiddle,您可以复制这个bug:。(我没有使用load()方法,而是使用了html(),正如您所看到的,性能损失仍在发生)

这里有一个半无用的代码片段,因为stackoverflow迫使我放一个(我不会把我的全部代码放在这里…):
$('a')。在('click',函数(){
if($(this.attr('href')='#test1'){
加载模板(1);
}否则{
加载模板(2);
}
});
加载模板(1);
函数加载模板(模板){
如果(模板==1){
$('.container').html('');
添加粒子();
}否则{
$('.container').html('模块2');
}

}
您的问题在于以下两段代码:

// This code is executed every time a link is clicked
$('a').on('click', function () {
    if ($(this).attr('href') == '#test1') {
        loadTemplate(1);
    } else {
        loadTemplate(2);
    }
});

// This function is also executed everytime a link is clicked
function loadTemplate(template) {
    if (template == 1) {
        $('.container').html('<canvas id="particles-canvas" width="1000" height="400" 
                              style="background-color: #000;"></canvas>');
        addParticles();
    } else {
        $('.container').html('<h1>Module 2</h1>');
    }
}
jQuery
此外,生成粒子的代码,
addParticles()
,存在缺陷。一段时间后,画布本身会变慢!所以在你的粒子生成代码中,有一些意想不到的行为。通过观察粒子30秒以上,你自己就能看到这一点。

我想我已经尝试过清空它了。。。我会试着在5分钟内报告。编辑:看,不是也发生了同样的性能损失吗?我还尝试用一个全局变量“删除”(关键字)循环,但它仍然不能提供更好的结果,即使它在进入模块2时停止循环。。。但是如果我有10个模块,像我现在这样加载它们不是更好吗?至于粒子代码,我知道它有缺陷。谢谢@古墓:你显然看错了。我修复了您的代码,以确保性能损失不是由于动画和容器的代码造成的。因此,我断言性能损失是由于您的粒子代码造成的。这是唯一剩下的问题(你应该能够自己解决)。“但是如果我有10个模块,像我现在这样加载它们不是更好吗?”我理解你的方法,但是如果我有多个画布,使用empty().append()不是更明智吗?使用hide()/show()并不能真正解决我的问题,因为画布只绘制了一次!我要看看粒子代码是否真的是性能损失的原因。谢谢我需要使用cancelAnimationFrame。我试过了,但实际上没有正确地使用它,因为我的目标是循环,而不是“requestId”!无论如何谢谢你!我只是将粒子脚本更改为最小值,以查看这是否是问题所在,但解决方案是cancelAnimationFrame。再次感谢您的帮助,谢谢您:)解决方案:jsfiddle.net/c7zgp8L1。我需要使用cancelAnimationFrame。我试过了,但实际上没有正确地使用它,因为我的目标是循环,而不是“requestId”!
<a href="#test1">Module 1</a>
    <a href="#test2">Module 2</a>

<div class="container1">
    <canvas id="particles-canvas" width="1000" height="400" style="background-color:#000;">
    </canvas>
</div>
<div class="container2">
    <canvas id="particles-canvas" width="1000" height="400" style="background-color:#000;">
    </canvas>
</div>
// Initialisation of Module 1
loadTemplate(1);
addParticles();

// Don't re-build the modules but simply toggle their appearance:
function loadTemplate(template) {
    if (template == 1) {
        $('.container2').fadeOut(function() {
            $('.container1').fadeIn();
        });
    } else {
        $('.container1').fadeOut(function() {
            $('.container2').fadeIn();
        });
    }
}