Capítulo 841 de 859

Chapter 841: Rendering on Demand (Manual)

Core Idea

Most three.js examples render continuously via a requestAnimationFrame loop, which wastes power/battery for scenes that aren't animating — rendering once and then only in response to actual changes (input, loaded data, resize) is often the better choice for non-game apps.

Key Concepts

  • Render-on-demand trigger points: render once at startup, then again whenever something actually changes — resource loads finishing, external data arriving, user input, or camera changes.
  • OrbitControls change event: fires whenever the controls move the camera, giving a natural hook to re-render without a continuous loop.
  • The damping infinite-loop trap: with enableDamping on, controls.update() (needed every frame while damping settles) itself fires another change event — calling render directly from change would recurse forever, so you instead request a frame only if one isn't already pending.
  • requestRenderIfNotRequested: a guarded wrapper around requestAnimationFrame(render) using a boolean flag, ensuring multiple rapid change events collapse into a single upcoming render rather than queuing many.
  • GUI-triggered renders: a GUI library's onChange callback can simply call the same "request a render" function so adjusting a control re-renders once, on demand.

Code Examples

let renderRequested = false;

function render() {
  renderRequested = false;
  renderer.render(scene, camera);
}
render();

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

controls.addEventListener("change", requestRenderIfNotRequested);
window.addEventListener("resize", requestRenderIfNotRequested);
  • What it demonstrates: coalescing multiple rapid-fire change events (camera movement, damping updates, resizes) into a single pending render via a guard flag.

Key Takeaways

  1. For non-animating scenes, render once and then only on actual change — this saves power, especially on battery-powered devices.
  2. Hook OrbitControls' change event (and window resize) to trigger a render rather than looping continuously.
  3. With enableDamping enabled, guard against infinite recursion by only requesting a new frame if one isn't already pending.
  4. GUI controls can drive the same on-demand render request as camera and resize changes.

Connects To

  • OrbitControls: the interactive control whose change event drives this whole pattern.