4

I'm in the process of learning VUE JS. I have a very basic SPA that routes between various pages.

I have a number of THREE JS demos that I've built in my spare time and I've noticed that if I jump between pages on them eventually they grind to a halt from a build up of memory. I want to avoid pasting their scripts in here as they're massive and I don't think the problem lies within them.

I think the problem the lies somewhere in between how I'm instantiating them and my lack of knowledge in VUE JS is what's causing me trouble with this problem.

Here is an example of one of the views I'm routing to in VUE JS:

<template>
    <div class="particles">
        <main-menu></main-menu>

        <div id="demo"></div>
    </div>
</template>

<script>
    import mainMenu from 'root/views/menu.vue';

    export default {
        components: { mainMenu },
        mounted() {
            var Particles = require('root/webgl/particles.js');
            var demo = new Particles();
            demo.run();
        }
    }
</script>

The original demos were built using traditional JavaScript (it's a ES5/6 class) and I was hoping that I could just plug them into my VUE SPA. Within each demo I am doing things like:

this.vsParticles = document.getElementById('vs-particles').textContent;

to load the shaders and to attach my THREE demo to a DOM element.

The issue I'm having is that somewhere something isn't being deleted. Within my demos i'm not creating anything new in the DOM and they run fine in non-SPA demos, but once I place them into a SPA app and jump between pages they build up.

I'm under the impression that when you change routes everything should get wiped. So all of the elements within my template tags and any objects I create within mounted(). But this doesn't seem to be the case and I'm just wondering is there something extra I need to include in VUE to completely clean everything up inbetween pages?

user1157885
  • 1,999
  • 3
  • 23
  • 38

2 Answers2

1

As Mathieu D. mentionned, you should move your require outside of the method.

Also, you may need to clear the WebGL context on the destroyed () Vue Component's hook.

I am not sure if it is the right way to do, but here is how I dispose it in my program :

this.renderer.forceContextLoss() this.renderer.context = null this.renderer.domElement = null this.renderer = null

Vincent Cantin
  • 16,192
  • 2
  • 35
  • 57
  • 1
    THREE.Renderer's method forceContextLoss is actually simulating context lose and using WEBGL_lose_context extension which is not supported if you target IE11. – None Jun 24 '17 at 15:42
  • 1
    Instead of writing long answer, i will share Gman's [answer](https://stackoverflow.com/a/23606581/1345303) – None Jun 24 '17 at 15:59
  • Thanks, destroyed hook + this fixed it. – user1157885 Jun 25 '17 at 12:18
0

Could you try to import particles.js out of mounted method ? For example, under your import of mainMenu ?

The import would be done one for all of your instanciation of Particles.

This will give you this code :

import mainMenu from 'root/views/menu.vue';
import Particles from 'root/webgl/particles.js';

export default {
    components: { mainMenu },
    mounted() {
        var demo = new Particles();
        demo.run();
    }
}

You could also read reactivity in depth in the documentation. It will help you understand how VueJS store and access data. I don't know if in your component code you store some data of your ThreeJS examples, but if so, it could consume some memory. In that case, use destroyed hook to clean your data.

tony19
  • 125,647
  • 18
  • 229
  • 307
Mathieu D.
  • 406
  • 3
  • 8