1. Intro
Un réglage simple, beaucoup de gouttes
L’interface est relativement simple : l’intensité de la pluie et un slider règlent la durée de vie d’une goutte après son arrivée au sol. Chaque goutte est gérée individuellement ; c’est idéal pour créer un code gourmand en ressources qui n’accomplit pas grand-chose pour autant. Chacun son hobby.
Avant de profiler, survolez 01-raining-mem/src/simulation/rain-world.js : le code est commenté et les méthodes ont des noms qui disent simplement ce qu’elles font.
On reconnaît l’influence d’Oh No More Lemmings, sur Atari ST, et de The Sandbox, sur iPhone 3GS. Le générateur procédural est basique : une variance maximale de ±2 pixels, quelques couleurs, et le tour est joué. C’est open source : servez-vous.
2. Créez le problème
Mode déluge
Passez en mode déluge. Demandez à Tony Montana — Scarface, oui, les références millenial — et le tour est joué :
Quelques étapes
- Ouvrez DevTools.
- Passez la pluie sur Rain ×4.
- Réglez la durée de vie des gouttes au sol au maximum.
Observez la mémoire
Les gouttes disparaissent, et pourtant la mémoire continue de monter. L’eau, elle, stagne à quelques pixels de haut.
Explorez le résultat
L’approche est exploratoire. Filtrez sur un type de classe lorsque vous cherchez quelque chose de précis. Sinon, sélectionnez une période dans la timeline et regardez ce qui ne colle pas : plus de 2 000 Raindrop dans le heap alors qu’il n’en reste qu’une poignée au sol ? Code smell.
3. Solution
La reference de trop
Spoiler alert. Pas de physique quantique ici : chaque goutte expirée quitte bien le paysage, mais elle est ajoutée à rainfallSamples. Ce tableau appartient au monde entier ; tant qu’il garde la reference, le garbage collector ne peut pas libérer la goutte.
Le même geste se produit lorsque le bouton Remove raindrops vide l’écran. Disparaître du canvas ne suffit pas : une reference JavaScript quelque part suffit à maintenir un object dans le heap.
Le correctif
Au moment où une goutte expire, ne la rangez pas ailleurs. La ligne marquée ci-dessous est à retirer — ici comme dans clearDrops().
01-raining-mem/src/simulation/rain-world.jselse if (now - drop.settledAt >= this.dropLifetime) {
drop.expiredAt = now;
this.rainfallSamples.push(drop); // ← retirez cette reference
continue;
}
Mesurez à nouveau
Rejouez exactement le même scénario : Rain ×4, durée maximale, puis enregistrement avec Allocations on timeline. Les anciennes Raindrop devraient pouvoir disparaître après leur expiration ; les barres bleues persistantes et leur compteur doivent alors nettement reculer.