Fans blowing up, high CPU usage?

Hi everyone,

I’m having a lot of trouble trying to finalise my website but for some reason it always causes the fans of my laptop to turn up after running it for a bit (fans don’t turn up straight away but happens after a minute or two). I’m new to three.js and I’m not sure my code is great… It would be great to know if it’s something I’ve done in my three.js code that’s causing the problem or if it’s my other code…

In my scene I have imported a glb scene(hand model with skeleton) and I’ve also created a plane geometry.

Here is my app.js code:

I also checked the Performance with Chrome Dev Tools, I think there’s something wrong with my init() and requestAnimationFrame, as it always says its a long task:

Any help is appreciated! Thanks in advance!

If your scene does not contain any animated 3D models, it’s actually better to remove the animation loop and only render when necessary. You can implement this kind of on-demand rendering by calling your render function only on certain events (e.g. app startup, user interaction, window resizing). Since you are using OrbitContorls, you can easily do this:

controls.addEventListener( 'change', render );

Which means the render() function is only called if the controls fire a change event.

Many official three.js example use this pattern, for example webgl_loader_gltf. I suggest you study it and try to adapt the code to your project.

On-demand rendering is in general a type of performance optimization without loosing rendering quality.

5 Likes

I would warn against this, you might end up requesting more frames than your screen can render. If you want to go down the route of “on-demand-rendering” - I suggest you throttle your rendering to at most once per screen refresh cycle. You can do that with requestAnimatioFrame and a bit of logic. I have similar mechanism in meep:

this code is under MIT, so feel free to use it.

1 Like

Also - I may be wrong, but you haven’t sorted the running tasks by length - they are in chronological order on the screenshot. What appears on the top of the list when you click “Total Time” or “Self Time” column header?

(If browser tells you init() is a long task it may be possible that somehow you are calling it over and over again. Usually init() shouldn’t take more than a couple of ms.)

1 Like

Hi, thank you so much for your reply and introducing on-demand rendering to me. I tried to implement this instead of having an animation loop and its working! It’s finally not blowing up my fans anymore, thank you! However I’m having some trouble to call the render() function on ‘click’…

I have two presets in my dat.gui that would change the hand’s posture when clicked. I tried .onChange(render) for the two presets but the model does not move unless I scroll or drag the model(which I understand is because we have orbitControl controls.addEventListener( 'change', render );). The slider parts of the gui works fine.

//hand position preset
gui.add(options, 'relaxed').name('👉Relax Hand').onChange(render);
gui.add(options, 'reset').name('👉Reset Hand Posture').onChange(render);

Besides the gui, I also wanted scene.remove( plane ) , scene.add( plane ) and changing the camera.position.set when clicking on certain div. I tried document.addEventListener('click', render); but it only works the very first time I click, any other times I click, the scene would not render unless I scroll or drag…

What am I missing here?
Sorry to bother again due to my lack of knowledge…

1 Like

Hi, I was able to solve my problem by implementing some code from https://threejsfundamentals.org/threejs/lessons/threejs-rendering-on-demand.html

This is what I did:
Although this did solve my problem, I’m afraid I do not fully understand the logic behind it…

function render() {
  renderRequested = false;

  orbit.update();
  renderer.render(scene, camera);
}
render();

function requestRenderIfNotRequested() {
  if (!renderRequested) {
    renderRequested = true;
    requestAnimationFrame(render);
  }
}

Now everything works when I call requestRenderIfNotRequested(); instead of render();

For example, in my dat.gui:

  //hand position preset
gui.add(options, 'relaxed').name('👉Relax Hand').onChange(requestRenderIfNotRequested);
gui.add(options, 'reset').name('👉Reset Hand Posture').onChange(requestRenderIfNotRequested);

What if my Scene is having animated 3D model and it’s running when window is out of focus with the help of web worker? I’m facing the issue with slowly increasing memory and CPU usages.