Video frames give you the film; Three.js gives you a scene drawn in code that changes angle as you scroll. The risk is the scene drawing nonstop, even when idle or off screen, and heating up the phone. Here you measure, in a headless Chromium, how many times the scene draws in each situation, and you watch the common mistake fail.
1Draw on demand: only when the scroll progress has changed
2Density cap (1.5) and offscreen pause with IntersectionObserver
3Count the draws with Playwright: idle, scrolling, offscreen, and reduced motion
4How much Three.js weighs on the page
Goal: measure a Three.js scene that only draws when the scroll changes, pauses off screen, and respects reduced motion.
01 · When the scene draws
On-demand drawing: each question is a reason NOT to draw. Click each step.
reduced motion: one frame only
Click each block in the diagram to see what it does.
The common mistake is the tutorial loop: requestAnimationFrame calling render() 60 times a second, forever.
02 · The heart of the kit scene
Page kit/site-three/index.html: four rings at different depths; the camera moves with the scroll. Three.js 0.186.1 (npm, 10/19/2026), copied into vendor/.
Excerpt · kit/site-three/index.html
// On demand: only draws when scrolling changed the progress and the scene is on screen.
const talvez = () => {
pedido = false;
if (!visivel) return;
const p = progresso();
if (Math.abs(p - ultimo) < 1e-4) return;
ultimo = p; desenhar(p);
};
const agendar = () => { if (!pedido) { pedido = true; requestAnimationFrame(talvez); } };
03 · Measure the draws
three-medir.mjs scrolls the page in a headless Chromium and reads window.__renders in each situation.
Chromium 156.0.8078.4 (Playwright 1.64.0)
parado 0 · rolando 30 · fora da tela 0 · reduzir 1 · DPR 1,5 (tela com densidade 3)
OK: parado 0 · rolando 30 · fora da tela 0 · reduzir 1 · DPR 1,5
saída: 0
PESO: js 2,12 · html/css 0,00 (MB)
three.js com gzip -9: 415205 bytes
Idle and offscreen: zero. With reduced motion: one frame only. The last two lines are the weight: 2.12 MB raw (unminified), 0.42 MB with gzip -9. Servers usually compress JS; JPEG barely compresses. Measure what will travel over the wire before comparing with the film.
FALHA: desenhou 103 vezes parado (devia ser 0)
FALHA: desenhou 81 vezes fora da tela (devia ser 0)
FALHA: com reduzir movimento desenhou 83 vezes (devia ser 1)
saída: 1
With ?sempre=1 the page turns on the tutorial loop. The numbers vary on every run; the failure does not.
04 · Video frames or Three.js?
Both fit on the same page; each does one thing well.
1. Frames
Real photo, material, hard light: what a generator or a camera does better than code.
The weight grows with the length of the film.
2. Three.js
Shapes, diagrams, particles, pieces that react to the mouse or change color: everything drawn on the fly.
The weight is the library (2.12 MB raw, 0.42 MB with gzip here) and the GPU's work on each draw.
3. Together
A frame film in the opening and a Three.js piece in a section below. Each with its own rule: frames in the bitmap window, scene on demand.
The right library for each motion piece is in course 3 (lesson 6).
05 · Practice
Measure, break, and fix.
E1 · Measure
5 min
Run the "measure the scene and the weight" block.
Done when: The line starts with OK: parado 0 · rolando (the number of draws while scrolling varies with the machine), ends with fora da tela 0 · reduzir 1 · DPR 1,5, and saída: 0 follows.
E2 · The mistake
5 min
Run the same meter with ?sempre=1 at the end of the URL (the "common mistake: always drawing" block).
Done when: Three FALHA: desenhou … lines and saída: 1.
E3 · Your scene
20 min
Copy kit/site-three to a folder of your own and swap the rings for another shape (TorusKnotGeometry, for example) and the material color. Keep the maybe function and the density cap. Serve the folder and measure.
Done when: The three-medir.mjs in your folder answers OK: parado 0 … reduzir 1 with saída: 0.
06 · Lesson quiz
The explanation appears after you answer.
Question 1 of 4
The page is still, with the Three.js scene on screen. How many times per second should it draw?
Correct
Draw on demand: only when the scroll progress has changed. Drawing the same image 60 times per second drains the battery and heats up the phone.
Not that one
Draw on demand: only when the scroll progress has changed. Drawing the same image 60 times per second drains the battery and heats up the phone.Review: When the scene draws
Question 2 of 4
On a phone with devicePixelRatio 3, the kit draws at density 1.5. Why?
Correct
The GPU's workload grows with the square of the density: (3 ÷ 1.5)² = 4. The cap is an engineering choice, not a library limit.
Not that one
The GPU's workload grows with the square of the density: (3 ÷ 1.5)² = 4. The cap is an engineering choice, not a library limit.Review: When the scene draws
Question 3 of 4
The meter shows "fora da tela 85". What is missing from the page?
Correct
Off screen, nobody sees the drawing. The observer says when the canvas has left, and the check stops before the render.
Not that one
Off screen, nobody sees the drawing. The observer says when the canvas has left, and the check stops before the render.Review: When the scene draws
Question 4 of 4
What does the kit's page do with "reduced motion" turned on?
Correct
Whoever asked for less motion gets the scene still, whole. The meter checks it: reduzir 1.