Achille 746
ACHILLE746
ExpertisesProcessusRésultatsPortfolioTechnologiesBlogFAQ
Lancer un projet
Accueil›Blog›Web Immersif & WebGL›Optimiser les performances WebGL : draw calls, instancing, LOD et textures
⚡WEB IMMERSIF & WEBGL

Optimiser les performances WebGL : draw calls, instancing, LOD et textures

10 JUILLET 2026•Par l'équipe Achille 746•10 min de lecture

Une scène Three.js qui tourne à 60 fps en développement sur un MacBook Pro M3 peut tomber à 15 fps sur le smartphone mid-range de votre utilisateur. WebGL est puissant mais impitoyable : chaque draw call, chaque texture non compressée, chaque shader non optimisé se paye en latence. Ce guide couvre les techniques d'optimisation qui font réellement la différence en production : réduction des draw calls, LOD, compression de textures, instancing, frustum culling et profiling GPU.

Profiler d'abord, optimiser ensuite

Avant d'optimiser quoi que ce soit, mesurez. Three.js expose ses statistiques via la librairiestats.js: FPS, MS par frame, MB de mémoire. Pour une analyse plus fine du goulot d'étranglement, l'onglet Performancede Chrome DevTools permet d'enregistrer une session GPU et de distinguer les frames CPU-bound (code JavaScript trop lent) des frames GPU-bound (trop de géométrie ou de fragments à traiter).

import Stats from 'stats.js';

const stats = new Stats();
stats.showPanel(0); // 0: fps, 1: ms, 2: mb
document.body.appendChild(stats.dom);

function animate() {
  stats.begin();
  // ... rendu
  stats.end();
  requestAnimationFrame(animate);
}

L'extension Chrome Spector.jsest l'outil de référence pour inspecter les draw calls WebGL : elle capture un frame et liste chaque appel WebGL avec son coût GPU, les textures et les shaders impliqués. Indispensable pour identifier les draw calls redondants ou les textures non optimisées.

Réduire les draw calls : la règle numéro un

Chaque appel renderer.render() → gl.drawElements() est un draw call. Le CPU doit préparer les données, les envoyer au GPU, puis le GPU les traite. Le temps de préparation CPU est fixe par draw call — indépendamment du nombre de triangles. Avoir 1 000 draw calls de 10 triangles chacun est bien plus lent que 1 draw call de 10 000 triangles.

Instanced Meshest la solution pour rendre des milliers de copies d'un même objet avec un seul draw call. Au lieu de créer 1 000 Mesh identiques, on crée unInstancedMesh avec une capacité maximale et on définit la transformation de chaque instance via une matrice :

const count = 5000;
const geometry = new THREE.SphereGeometry(0.05, 8, 8);
const material = new THREE.MeshStandardMaterial({ color: 0xC026D3 });
const instancedMesh = new THREE.InstancedMesh(geometry, material, count);

const matrix = new THREE.Matrix4();
const position = new THREE.Vector3();

for (let i = 0; i < count; i++) {
  position.set(
    (Math.random() - 0.5) * 20,
    (Math.random() - 0.5) * 20,
    (Math.random() - 0.5) * 20
  );
  matrix.setPosition(position);
  instancedMesh.setMatrixAt(i, matrix);
}
instancedMesh.instanceMatrix.needsUpdate = true;
scene.add(instancedMesh);

5 000 sphères en 1 draw call au lieu de 5 000. Le gain de performance est typiquement de 10x à 100x selon le GPU et le CPU.

Fusionner les géométries avec BufferGeometryUtils

Pour les objets statiques qui n'ont pas besoin de transformations individuelles (décors, terrain, détails environnementaux), fusionner les géométries en une seule viaTHREE.BufferGeometryUtils.mergeGeometries()produit un draw call unique. La contrepartie est qu'on perd la possibilité de déplacer ou masquer les géométries fusionnées individuellement — acceptable pour les éléments de décor statiques.

Level of Detail (LOD) : adapter la complexité à la distance

Un modèle 3D à 50 000 polygones rendu à 2 pixels de large est un gaspillage pur. Le LOD (Level of Detail) résout ce problème en substituant automatiquement une version simplifiée du modèle quand l'objet est loin de la caméra.

const lod = new THREE.LOD();

// Version haute résolution (proche)
const highGeo = new THREE.SphereGeometry(1, 32, 32);
lod.addLevel(new THREE.Mesh(highGeo, material), 0);

// Version moyenne (distance intermédiaire)
const medGeo = new THREE.SphereGeometry(1, 16, 16);
lod.addLevel(new THREE.Mesh(medGeo, material), 10);

// Version basse résolution (loin)
const lowGeo = new THREE.SphereGeometry(1, 6, 6);
lod.addLevel(new THREE.Mesh(lowGeo, material), 30);

scene.add(lod);
// lod.update(camera) doit être appelé dans la boucle d'animation

Textures : compression et mipmap

Les textures représentent souvent 80 % de la mémoire GPU et du temps de chargement d'une scène. Deux optimisations incontournables : la compression GPU et lesmipmaps. Les formats de compression GPU (KTX2 avec UASTC/ETC1S) réduisent la taille en mémoire GPU de 4x à 8x par rapport au PNG/JPEG décompressé, avec une qualité visuelle quasi identique. Three.js supporte KTX2 via KTX2Loader et le transcoder Basis Universal.

import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';

const ktx2Loader = new KTX2Loader()
  .setTranscoderPath('/basis/')
  .detectSupport(renderer);

const texture = await ktx2Loader.loadAsync('/textures/albedo.ktx2');
texture.generateMipmaps = true; // automatique pour KTX2

Les mipmapssont des versions pré-calculées de la texture à différentes résolutions (512, 256, 128...). Quand l'objet est loin, le GPU utilise la version basse résolution, évitant les artefacts de moiré et réduisant le nombre de texels à échantillonner. Three.js génère les mipmaps automatiquement au chargement — vérifiez que texture.generateMipmaps = true(valeur par défaut pour les textures non-compressées).

Frustum culling et occlusion culling

Three.js effectue automatiquement le frustum culling: les objets en dehors du champ de vision de la caméra ne sont pas envoyés au GPU. Pour les scènes avec beaucoup d'objets, activer mesh.frustumCulled = true(valeur par défaut) est suffisant pour les objets volumineux. Pour des objets très petits ou des scènes de type couloir (FPS, visite virtuelle), une implémentation d'occlusion culling via des queries WebGL ou une octree spatiale peut réduire considérablement le nombre de draw calls.

Web Workers pour les calculs lourds

Les calculs CPU lourds — génération procédurale de géométrie, pathfinding, physique — bloquent le thread principal et font tomber le framerate, même si le GPU est rapide. Les Web Workers exécutent ces calculs sur un thread séparé. Three.js peut transférer des BufferGeometryvers un Worker via geometry.toJSON() ou les transferables ArrayBuffer. Pour les effets de particules complexes calculés sur GPU, les GPGPU (General Purpose GPU) via GPUComputationRendererde Three.js ou via WebGPU sont l'étape suivante vers des simulations de millions de particules en temps réel — une spécialité que nous explorons dans nos projets d'expériences Three.js immersives.

“60 fps n'est pas un objectif de luxe — c'est le seuil en dessous duquel votre expérience immersive devient une expérience frustrante. L'optimisation WebGL est autant du design que de la performance.”

Optimiser une scène WebGL est un travail de mesure, d'hypothèse et de validation continue. Il n'existe pas de recette universelle — chaque scène a son propre goulot d'étranglement. Ce que nous savons, c'est que les sites web immersifs que nous développons depuis Brive-la-Gaillarde pour nos clients en Nouvelle-Aquitaine et au-delà doivent tourner parfaitement sur l'ensemble des appareils de leurs utilisateurs. Pour concevoir une expérience WebGL performante et mémorable, découvrez notre expertise Web Immersif ou prenez contact.

Article précédentShaders GLSL : les effets visuels avancés qui rendent le web immersifTous les articlesArticle suivantAgence web et IA à Brive-la-Gaillarde : full-stack, WebGL et cybersécurité
Partager cet article :Twitter / XLinkedIn

Articles liés

⚡
Rust + IA : le duo parfait pour des applications ultra-performantes et sûres
7 min de lecture
→
🌐
WebAssembly avec Rust : performances natives dans le navigateur et au-delà
8 min de lecture
→
🌐
Three.js : créer des scènes 3D interactives dans le navigateur
10 min de lecture
→
✨
Shaders GLSL : les effets visuels avancés qui rendent le web immersif
9 min de lecture
→

Votre scène 3D rame sur les appareils de vos utilisateurs ?

Nous auditons et optimisons vos scènes WebGL pour des performances 60 fps sur l'ensemble des appareils cibles, du desktop haut de gamme au smartphone mid-range.

Discuter de votre projet →