Ways to refresh a canvas element without requiring a full page reload

My goal is to restart a canvas on a website without reloading the page, making the restart dynamic. However, I've noticed that after multiple restarts, the animation slows down and memory usage increases.

The situation is complicated by my use of MeteorJS with IronRouter framework to load pages. Changing the URL only removes nodes from the DOM without completely refreshing the 'page'. Returning to the page with the canvas could be considered a dynamic canvas restart, but I haven't found a solution for that either.

I am addressing this issue from two perspectives:

  1. A simple page where a button triggers the canvas restart.
  2. Applying the solution to MeteorJS with IronRouter and repeatedly navigating back to my page with the canvas.

Note: My canvas content includes WebGL (in ThreeJS).


1. Deleting and re-initializing canvas dynamically.

In this scenario, I encounter the following issues:

  • Animation not smooth
  • Memory increase. Specifically:

https://i.sstatic.net/M41kO.png
(source: hostingpics.net)

  1. Page loaded, playing with canvas / 2. Restarting the canvas 30-40 times (I continuously restarted so I'm unsure why the increase isn't linear) / 3. Playing with canvas / 4. Closing the tab (reloading the page only frees a small fraction of what has been consumed)

There have been few questions asked on SO about solving these issues, and implementing partial solutions does improve the problem. Two main suggestions I've come across are:

  • Clean up canvas-related parts (nodes, variables, functions) from the DOM (Meteor already does this, but in this case it's insufficient to prevent the issues).
  • If requestAnimationFrame has been called, assign it to a variable so that cancelAnimationFrame(variable) can stop it. This seems to prevent frame rate drops, although memory consumption remains high, at least ensuring smooth movements.

Even with these solutions, the memory problem persists.

Here is an example: http://codepen.io/Astrak/pen/RNYLxd


2. In MeteorJS: struggling with the implementation.

This is what I tried in my app, declaring

id=requestAnimationFrame(myAnimation)
globally:

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

Despite these instructions, the animation becomes sluggish much faster with MeteorJS compared to the previous example, becoming unresponsive after just 3-4 page changes. The same memory issue persists.

Thank you for any comments or answers, and happy coding :)


Related questions:

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

Answer №1

If you're facing memory issues, I suggest using Chrome's javascript profiler to troubleshoot. You can analyze snapshots before and after a canvas reload to identify any objects that are not properly released from memory.

The root of the problem often lies in event handlers and closures. For instance, attaching a function to the window object's onresize event can prevent objects referenced within that function from being cleared from memory as long as the window is open. Therefore, it's important to remove event handlers from global objects if you want to update page content without refreshing the entire browser session.

Closures can also cause memory leaks by creating links between a function's scope and the variables it references. For more information on this topic, check out this insightful article: https://www.example.com/memory-leak-article

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble handling file uploads in Laravel via JQuery Ajax requests

When attempting to upload a CSV / Excel file and receiving it through an ajax request, the process is not functioning as anticipated. I employed a formdata object to upload the files in this manner: const formData = new FormData() formDa ...

Achieving checked checkboxes based on already selected values in AngularJS

function Test1Controller($scope) { var storeid = window.localStorage.getItem("storeid"); var serverData = ["Samsung Galaxy Note", "Samsung Galaxy S6", "Samsung Galaxy Avant","Samsung Galaxy Young"]; $scope.items= [] ; var selectedvalue="Samsu ...

Ways to retrieve slider value when button is clicked?

I am currently working on a range-slider that has two ranges and I need to retrieve the slider value in my javascript code. Here is my approach so far: <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.cs ...

Issue with Flask-Cors in Nuxt with Flask and JWT authentication implementation

I have exhausted all the available solutions to my issue, but I still can't seem to pinpoint the problem. Despite trying every solution out there, nothing seems to be of any help. Every time I make a request, the browser blocks it due to CORS Policy ...

Matching an element that contains a specific string in JS/CSS

I'm currently faced with an HTML file that's being generated by an outdated system, making it tricky for me to control the code generation process. The structure of the HTML code is as follows: <table cellpadding=10> <tr> ...

Numerous animated elements within A-frame

Is there a way to incorporate animation into an A-Frame glTF model, causing it to smoothly move 5 spaces to the left and then 5 spaces forward? Below is my current code: <a-gltf-model color="#FFFFFF" width="1" height="1" de ...

Encountering an error message while trying to use `npm i`

I am attempting to set up the environment in order to run tests on JavaScript. I am using Windows 10 and Python 2.7. However, when I input the command 'npm -i', I receive an error message: https://i.stack.imgur.com/j2WXE.jpg To try and resolve ...

Charting with multiple series

I am exploring a unique approach to creating a timeline chart. I am seeking advice on the best way to implement this in the world of JavaScript. My challenge is to create interactive milestones with descriptive text displayed on the Y axis, while displayi ...

Retrieve the $scope object within an isolated directive

Is there a way to modify a $scope variable from within an isolated directive? I've experimented with the '@, =, &' syntax in the directive scope but haven't been successful. Here's a simplified version of my code: JS app.co ...

The accumulation of keydown events in VueJs

Currently, I am developing a feature where a <textarea> field starts to fade out as soon as the user begins typing using v-on:keydown. However, if the user continues typing, the fading effect resets to keep the opacity: 1. Unexpectedly, the behavior ...

Javascript conditional testing

I need help coding a <div> to display only if the numeric input is 18 or above and the YO option is chosen. Any guidance on this would be highly appreciated. See the code snippet below. <input type=numeric id=ageSelf ng-model="ageSelf" style="c ...

Steps for assigning a 404 status code upon promise rejection

My approach to testing the login functionality involves using promises and chaining them. If the user enters an invalid password, the data is rejected; otherwise, it is resolved. I then verify if the user is logged in successfully by chaining these methods ...

Retrieve an item from an array based on the unique ID value of the button that was clicked using

I am working with a phones array that is populated with JSON data: var phones = [ { "age": 0, "id": "motorola-xoom-with-wi-fi", "imageUrl": "img/phones/motorola-xoom-w ...

Scrolling and hovering now triggers the fixed button to toggle class seamlessly

Currently, I am attempting to modify the class of a button on my website. The initial state of the button is wide, but as the user scrolls, it should shrink in size. When hovering over the shrunken button, it should expand back to its original width. Alt ...

Issue with spyOn function being called in Jasmine test for Angular 2

Within the initialization of my Angular component, there is a function: populateForm(id:String, index:number){ let blogs = this.blogsService.returnBlogs() blogs.map((blog:Blog)=>{ blog._id === id ? this.blogsService.populateForm.next({blog: ...

Database hosted on Heroku platform

Curious to know, if you utilize Heroku for hosting, what database do you prefer? Do you lean towards PostgreSql, MongoDB, or another option altogether? I initially developed a bot using sqlite3, but quickly discovered that Heroku does not support it and ...

The ng-click event is not triggering the Controller Function as expected

This is the Code for My View <div ng-controller="signupCtrl"> <ul class="list-group" > <li class="list-group-item"> <div class="form-group"> <input type="text" ng-model="signupCtrl.firstName"> ...

Utilizing ng-repeat, ng-grid, and ng-click in Angular: A comprehensive guide

I'm encountering an issue with populating a table using ng-repeat after a cellTemplate ng-click. cellTemplate: '<div ng-click="foo()" ng-bind="row.getProperty(col.field)"></div>' Within this foo method, I am tryi ...

Enable the input field once the checkbox has been marked

Here is a checkbox example: <div class="form-group"> <input type="checkbox" id="examination" class="form-control" name="exam" placeholder="Enter Title"> <label>Enable Exam</label> </div> Additionally, I have a disabled inpu ...

The method expression does not match the Function type specified for the mongoose Model

Encountered a perplexing error today that has eluded my attempts at finding a solution. const mongoose = require('mongoose'); const userSchema = mongoose.Schema({ name: {type:String, required:false}, birthday: {type:String, required:f ...