How can we address performance concerns in Three.js during the initial rendering of a mesh? Are there any

In my current project, I am dealing with 100 BoxGeometries, each containing its own image (approximately 10kb). Unfortunately, I have noticed performance issues and frame skipping on mobile devices during the initial rendering of these boxes, and I am looking for ways to resolve this.

Currently, I preload all images and create textures before adding the boxes:

let loader = new THREE.TextureLoader()

for(let img of assets) {

    loader.load(img.url, texture => {

        textures[img.name] = texture 
        assets.splice(assets.indexOf(img),1)
        if(!assets.length) {
            addBoxes()
        }

    })

}

The boxes are then laid out in a grid, which can be illustrated using pseudo-code:

textures.forEach((texture,i) => {

    let box = new THREE.Mesh(
        new THREE.BoxGeometry(1, .04, 1),
        [
          blackMaterial,
          blackMaterial,
          new THREE.MeshBasicMaterial({
                map: Controller.textures[boxMaterial.postID]
            }),
          blackMaterial,
          blackMaterial,
          blackMaterial
          ]
    )

    box.position.x = (i % 10 - 5)
    box.position.z = (Math.floor(i / 10) - 5)

    scene.add( box )

})

requestAnimationFrame( step )

I am using a THREE.OrthographicCamera to pan and zoom around the boxes. When the boxes first appear on screen, there is a spike in memory usage. However, once all boxes have been loaded and seen, the memory consumption decreases significantly, resulting in smooth performance without any dropped frames.

It is worth noting that after 6 seconds, the memory usage stabilizes once all boxes have been viewed:

https://i.sstatic.net/Cumij.png

To address this issue, I tried setting the frustumCulled parameter on the boxes:

box.frustumCulled = false

This solution improved performance in some aspects. Once loaded, the performance is consistently smooth, and the memory issues are eliminated. However, I am facing challenges with detecting when all meshes have finished loading, resulting in slow initial load times and jittery animations and interactions occurring too early.

While eager loading may increase the initial load time, it could potentially solve the memory issues caused by lazyloading. Are there any other alternatives I should consider? Is setting box.frustumCulled the most effective approach?

Additionally, I am exploring options for implementing event listeners for loading activities. Ideally, I would like to preload all boxes as if they had already been viewed once, and only trigger an init method once the system is fully prepared.

Answer №1

Here are some suggestions:

1. Utilize Shared Geometry

To optimize your code, consider sharing the geometry definition for all cubes and then applying scaling transformations to adjust their sizes individually. This way, you only need to upload one geometry definition to the GPU.

let boxGeometry = new THREE.BoxGeometry(1, .04, 1);
textures.forEach((texture, index) => {
    let cube = new THREE.Mesh(
        boxGeometry,
        [
          blackMaterial,
          blackMaterial,
          new THREE.MeshBasicMaterial({
                map: Controller.textures[boxMaterial.postID]
            }),
          blackMaterial,
          blackMaterial,
          blackMaterial
          ]
    );

This approach can improve performance by reducing the number of geometry uploads.

2. Pre-render Geometry

Consider creating the cubes with a transparent material upfront and adding textures later. By pre-rendering the geometry, you may speed up the initial rendering process.

3. Explore InstancedMesh

Investigate using InstancedMesh in three.js to potentially enhance overall rendering performance when dealing with multiple cubes.

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

Enable/Deactivate Chrome Extension Content Script

I am exploring ways to enable users to toggle a Chrome content script with the click of a button. It appears that using chrome.browserAction is the most efficient method for achieving this. However, when I include the following code snippet: chrome.brow ...

Assistance with Collision Detection in HTML5 Canvas using JavaScript

Attempting to create a platformer game using HTML5 and the canvas feature. I managed to implement collision detection with rectangles, but encountered issues when adding multiple rectangles. I have a function that adds new objects to an array with attribut ...

ESLint is flagging an issue where the TypeScript type declaration is attempting to reference a type that

Currently, I am in the process of developing a builder that incorporates various types. The method I use to define the type is as follows: export type BuilderInterface<T> = { [key in keyof T]: (arg: T[key]) => BuilderInterface<T>; } & ...

Incorporating a new Autodesk Forge extension

Hey there! I'm currently working on integrating a forge extension into my viewer, but I seem to have missed something along the way. I've been following this helpful guide: Here's the code snippet that I'm using: <body> < ...

Unlocking the secrets of the Fibonacci function through mathematical equations

Looking for a better way to calculate the fibonacci function using a mathematical formula. I've tried the following formula without success: fib(n) = ((1 + 5^0.5) / 2)^n - ((1 - 5^0.5) / 2)^n / 5^0.5 const fib=(n)=>{ return ((1+(5**0.5))/2)* ...

Download a complete website using PHP or HTML and save it for offline access

Is there a way to create a website with a textbox and save button, where entering a link saves the entire website like the 'save page' feature in Google Chrome? Can this be done using PHP or HTML? And is it possible to zip the site before downloa ...

Exploring the selection box model using TypeScript and Knockout

     Seeking assistance in converting a Knockout.js code to Knockout with Typescript. The current Knockout.js code is operational, but I am encountering difficulties in integrating it with Typescript...      View:     <select data-bi ...

Retrieving the current page in Vue.js

When working with Vue, I use the following code for pagination: <b-pagination :total-rows="props.total" first-number last-number align="right" prev-class="prev-item" next-class="next-item" class=&quo ...

Breaking apart elements in an array of objects

Working on a react/javascript exercise, I'm struggling to grasp the concept of using splice(). My task involves randomly assigning 4 out of 8 cards to 2 players. Although everything seems to be functioning correctly, the part that puzzles me is the pr ...

I'm having trouble displaying the result of my calculation in the code. Could it be because I forgot to include an output tag?

I am attempting to develop a Miles Per Gallon (MPG) calculator using Javascript. However, I'm encountering difficulties with displaying the results once the "Calculate" button is pressed. <html> <head> <title> MPG Calculator </ti ...

Which property is best suited for styling a phone number field in the MUI data grid in ReactJS?

I previously utilized the pattern attribute for input fields in pure HTML, but now I no longer have any input fields. What should be my next steps? Can you provide me with a reference in the MUI documentation? https://i.stack.imgur.com/ ...

Tips for enhancing the clarity of elements in KineticJS

I'm new to using Kinetic JS, and while I think it's a great library, I'm having trouble with the resolution of the elements. I know that Kinetic JS doesn't use SVG, but the resolution is not up to par. I'm creating circles and othe ...

Adjusting spotLight.shadowCameraFov dynamically

Help needed with changing the shadowCameraFov property of a spot light object using onChange method in Javascript: gui.add(controls, 'spotCameraFov', 30, 270).onChange( function (e) { spotLight.shadowCameraFov = e; co ...

Tips for adjusting UI with Media queries based on screen dimensions

Looking for a better solution I currently have 5 sets of items. Button Text Dropdown Pagination Icon For larger screen sizes, specifically @media (min-width: 990px) {} I would like all items to be in a single row, like so: [button][Text][Dropdown][Pagi ...

Using SVG in a Vue standalone script without the need for a build step is easy with the

When I attempt to utilize Vue as a standalone script in an HTML file, my inline svg icons are rendered as solid filled squares instead of their intended shapes. This issue persists when using both Vue 2 and Vue 3 as standalone scripts. Although there are ...

Is it possible to perform a PHP redirect after the headers have been

I am encountering an issue with a function that needs to redirect the page once a variable is set. The challenge arises from the fact that this function is located at the bottom of the PHP page. As a result, I have already displayed a significant amount ...

Console does not display AJAX response

Currently, I am utilizing AJAX to fetch form data from a Django application and my objective is to display the response in the console. $.ajax({ type: 'GET' , url: url, data: {'PUITS': PUITS ...

Restrict access to class/function names using ".name" in Typescript

Is there a simple method, like a tslint rule, that can help us avoid using MyClass.name or myFunction.name? We want to ensure that no developers inadvertently use these, as the minification process may alter method names. Appreciate any assistance on thi ...

How can Typescript and nodejs be utilized to develop an unconventional application that goes beyond the typical web or API functionalities?

Do you think it's acceptable to utilize nodejs and typescript for creating a service that is neither an API nor a web application? At the moment, I am developing a service that regularly reads email attachments, sends them to another app, saves inform ...

Verify your identity using Google reCaptcha during Passport authentication

I am currently working on integrating google reCaptcha into my signup form's back-end, which already includes passport authentication. The code I have so far looks like this: app.get('/signup', function(req, res) { // render the ...