What is the best way to clear memory after using a temporary THREE.js renderer and container?

Within my javascript "Image SNAP Function," I am utilizing a temporary DOM div container along with a THREE.js renderer to generate a high-resolution image file of the current scene. This allows the user to view the image outside the browser or save it as a .JPG file.

Although the functionality works as intended, I have noticed that an additional 0.14Gb of memory is utilized for each "snap" and is not released. This leads to a degradation in PC performance after multiple snaps. Releasing the memory involves closing the "app" (browser tab window), which is inconvenient for the user.

Despite attempting various commands within the Image Snap function to release the memory, none have proven effective.

Below is the code snippet for the Image Snap function:

function F_SNAP_JPG()           
{
    var bigContainer = document.createElement('div');
    bigContainer.style.cssText = 'id: "bigContainer", width: 4000, height:2200 '; 
    document.body.appendChild( bigContainer );
    bigContainer.innerHTML = "";

    var bigRenderer = new THREE.WebGLRenderer( {antialias:true , preserveDrawingBuffer: true} );    
    bigRenderer.setPixelRatio( window.devicePixelRatio );
    bigRenderer.setSize( 4000, 2200 );

    bigContainer.appendChild( bigRenderer.domElement ); 

//--------------------------------------------------------------------------------------------
// RENDER

    bigRenderer.render     ( scene, camera );
    
//--------------------------------------------------------------------------------------------
//... capture image for viewing or saving
    var strMime = "image/jpg";
    var fileURL = bigRenderer.domElement.toDataURL( strMime );          

    var Anchor = document.createElement('a');                         

    document.body.appendChild( Anchor ); 
    Anchor.style    = "display: none";
    Anchor.href     = fileURL;
    Anchor.target   = '_blank';
    Anchor.download = filename || 'unknown';
    Anchor.click(); 
    document.body.removeChild( Anchor ); 
    
    //--------------------------------------------------------------------------------------------
    //...attempt memory release

    bigContainer.removeChild( bigRenderer.domElement ); 

    bigRenderer.dispose();

    document.body.removeChild( bigContainer );  

    bigContainer.delete();  

}//... End of function

I am seeking a solution to release the memory without necessitating the closure of the browser tab window.


Update (Solution)

I came across a solution provided by Konstantin Eletskiy in a 2015 Stack Overflow post titled Clean up Threejs WebGl contexts.

The solution involves adding a single line

bigRenderer.forceContextLoss();

At the end of the F_SNAP_JPEG function. This addition effectively resolves the memory leakage issue experienced during snapshot generation.

Answer №1

I am in alignment with George's perspective. I have crafted a revised version that aims to alleviate some of the excessive code buildup.

Here are a few key points regarding the code snippet below:

  • I have employed a closure to facilitate the reuse of common elements.
  • While I have retained the sections involving the creation of the DOM structure using appendChild, it is worth noting that it may not be necessary.
    • It is worth mentioning that the variable bigContainer is actually redundant and can be eliminated.
const F_SNAP_JPG = ( function () { // TheJim01: Encapsulating this within an IIFE closure for element reusability

    const bigContainer = document.createElement('div');
    bigContainer.style.width = '4000px';
    bigContainer.style.height = '2200px';
    document.body.appendChild(bigContainer);

    const bigRenderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true });
    bigRenderer.setPixelRatio(window.devicePixelRatio);
    bigRenderer.setSize(4000, 2200);
    bigContainer.appendChild(bigRenderer.domElement);

    const Anchor = document.createElement('a');
    Anchor.style.display = 'none';
    Anchor.target = '_blank';
    document.body.appendChild(Anchor);

    return function () { // TheJim01: This is the main function that is invoked, so debug points can be set within this scope.

        bigRenderer.render(scene, camera);

        let fileURL = bigRenderer.domElement.toDataURL('image/jpg');

        Anchor.href = fileURL;
        Anchor.download = filename || 'unknown'; // TheJim01: It seems like the 'filename' parameter is consistently undefined. Is this an oversight?
        Anchor.click();
        Anchor.href = ''; // TheJim01: Clearing the dataURL string.

    };

})();

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

Issues with Async Ajax functionality are being reported specifically in Safari browsers when a redirect

Encountering issues with an async Ajax call not functioning in Safari while working perfectly fine in other browsers. The problem arises when there is a redirect/link on the button or anchor that triggers the Ajax function. Here's a basic example: & ...

Error encountered in Express Router middleware (`app.use() function must be provided with a middleware function`)

I've seen plenty of similar questions on this topic, but after reviewing them all, I still haven't found a solution. My current dilemma involves creating an app using Express Router, however I keep encountering the following error: app.use() re ...

Ways to Implement Horizontal Scrolling in Dojo FilteringSelect Component

The select field on my form contains option values that are over 250 characters long, making it difficult for users to read them within the select box. Is there a solution to make the select field scroll horizontally or wrap the lengthy text? ...

Can you extract information from the XML file and modify the anchor tags?

<description> <div class="field field-name-field-image field-type-image field-label- hidden"><div class="field- items"><div class="field-item even"><a href="/news/news/vg"> ...

Developing a trivia game using HTML and JavaScript

I'm in need of some serious assistance with creating a quiz using HTML. My goal is to have a web page where users can visit, take a quiz, and have their responses stored. Unfortunately, I don't have the knowledge or skills required to do this on ...

Avoid receiving a 404 error when using an invalid ID

When trying to set up my workoutId param, I encounter the following error: UnhandledPromiseRejectionWarning: CastError: Casting to ObjectId failed for value "5fb02bd8b61abc02" at path "_id" for model "Workout" If the workou ...

jQuery ajax doesn't function properly on the server, it only works locally

When I send a jQuery Ajax request from my front-end to the back-end to retrieve values for calculations, it works perfectly on my local web server. However, when I try it online, all I get is a result of 0 in my calculations, indicating that the Ajax respo ...

How to Make Client-Side Jquery Code Function in Karma Tests

I'm facing a challenging issue for which I can't seem to find a solution. In my React component, I am using jQuery to modify the classes of certain DOM nodes based on a click event. Here is a simplified version of the code: hide() { if ($(&ap ...

Tips for incorporating a Forgot/Reset password option into your #Firebase platform

In the project I'm working on, I am utilizing #AngularFire2. My goal is to incorporate a Reset / Forgot password link into the login page. Does anyone have suggestions on how to accomplish this task? I'm looking to get some insights from #AskFi ...

Updating ng-table within an Angular controller

Having encountered an unusual issue with ng-table. Here is a snippet of code from my controller: this.category = "Open"; this.category = ["Open", "Accepted", "Rejected"]; this.dataItems = []; var _this = this; this.$scope.$watch("vm.category", function( ...

Scrollbar becomes inactive following the loading of AJAX content

Having an issue with loading a div using Ajax. The div loads, however the scrollbar within it stops working afterwards. In Main.html, I load content from other HTML files like so: <div id="content1" > </div> The content is loaded as follows: ...

No change in the element's text content when clicking

I'm working on creating a timer that counts down from either 15 or 30 seconds. However, I'm having trouble changing the text value when the 15 button is clicked. Can someone help me figure out what's wrong? Thank you in advance HTML <h ...

How can you toggle the visibility of a text based on the selection of a jQuery radio button?

Is it possible to dynamically enable or disable a field based on the selection of a radio button? Here are the rules: The field should only be active when the "Inactive" radio button is selected Check out the code snippet below for reference: Radio B ...

Intercommunication of variables among components

My scenario involves two components, namely App and SomeComponent. I'm aiming to access a variable in App from SomeComponent. App: import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css& ...

Display various images based on different device orientations in UIWebView

Is there a way to display varying images in my HTML on a UIWebView, depending on the orientation of an iPhone? (I apologize if this question seems basic...) ...

There seems to be an issue with accessing /puffins/5f298d0ebcbaf254dcf282b3 at

Having trouble with my destroy route - it keeps returning an error. I've spent a lot of time trying to debug it but no luck yet. Can you lend a hand? All other CRUD routes are functioning correctly. //THE ROUTE app.delete('/puffins/:id', (re ...

Retrieve Image/png using an Extjs ajax request

Hello, I am currently working on an application that is designed to showcase dynamically generated images stored on a server. The process involves fetching the image, typically in PNG format, using an Ajax Request. The data retrieved appears as follows: ...

Stop users from being able to copy text on their smartphones' internet browsers

I am currently working on creating a competitive typing speed challenge using JavaScript. Participants are required to type all the words they see from a div into a textarea. In order to prevent cheating, such as copying the words directly from the div, o ...

I'm facing an issue in React where using onChange is causing all DOM elements to be cleared. The input form functions correctly when used with a button, but for some reason, the onChange event does not

Currently, I'm working on a grid that can be resized using two input fields in the application. The setup involves an input for cells across, an input for cells down, and a button to set the grid, which is functioning well. However, I would like to ma ...

Using Three.js to import and cast rays on a .obj model created in Blender

I have successfully imported a 3D terrain using Blender and the OBJLoader in Three.js. In addition, I have created a mesh (highlighted in yellow in the image below) that I want to follow the mouse cursor while it hovers over the terrain. I have attempted t ...