Blogue WebGL et technologies créatives

Conseils de performance WebGL pour les sites 3D mobiles

Gardez un site web 3D WebGL réactif sur les téléphones grâce à un flux de travail pratique : regroupement des appels de rendu, textures compressées, chargement progressif, résolution adaptative, paliers de qualité et tests.

Guide 9 min de lecture

Si votre site WebGL 3D semble lent sur un téléphone, commencez par établir un budget pour le travail du GPU, la mémoire, les octets réseau et le temps du fil principal. La solution pratique consiste à regrouper les appels de rendu, à livrer des textures compressées, à charger d'abord les actifs à plus faible détail, à effectuer le rendu avec un ratio de pixels contrôlé et à garder une expérience sans WebGL prête pour les appareils qui ne peuvent pas soutenir la scène.

Commencez par un budget de performance mobile

Notez les limites avant d'ajuster la scène. Mesurez le démarrage, le rendu en régime stable, le défilement, l'interaction et le moment où la page devient utile.

Pour la première passe, suivez :

  • La taille de transfert du JavaScript et des modèles avant et après la compression
  • Le nombre d'appels de rendu, de triangles, de matériaux actifs et la mémoire des textures
  • Les tâches du fil principal pendant le chargement et l'interaction
  • Le temps de rendu des images pendant que la caméra se déplace, et pas seulement une image au repos
  • Le Largest Contentful Paint (LCP), soit le temps nécessaire à l'affichage du plus grand contenu visible
  • Les pertes de contexte, les erreurs de mémoire insuffisante et les échecs de chargement d'actifs

web.dev recommande un LCP de 2,5 secondes ou moins pour au moins 75 % des visites de page. Considérez-le comme une cible de chargement de page, et non comme une promesse qu'une scène 3D lourde sera prête à ce moment précis. Affichez d'abord du contenu HTML utile à l'écran, puis chargez la scène.

Testez au moins un iPhone ou un iPad récent, un téléphone Android de milieu de gamme et un appareil Android à faible puissance. Notez le navigateur, le système d'exploitation, la taille de l'écran, le ratio de pixels de l'appareil, le type de connexion et l'état de la batterie. Un GPU de bureau ne peut pas remplacer un GPU de téléphone.

1. Réduire les appels de rendu grâce au regroupement

Moins d'appels de rendu donnent généralement plus d'air à une scène WebGL mobile. Un appel de rendu demande au navigateur et au GPU de lier un état et de dessiner un lot; une scène comptant de nombreux petits objets peut donc passer son temps à changer d'état plutôt qu'à dessiner.

Regroupez les objets qui partagent la même géométrie, le même matériau et la même texture. Utilisez l'instanciation pour les maillages répétés comme les cartes, les particules, le feuillage ou les composants de produit. Utilisez des atlas de textures lorsque plusieurs objets peuvent partager une seule texture, afin qu'un changement de texture ne scinde pas le lot.

MDN recommande de regrouper les appels de rendu et donne 1 000 sprites en un seul appel de rendu comme exemple de l'idée. Ne considérez pas 1 000 comme une limite universelle. Analysez la scène que vous livrez et trouvez le point où le temps de rendu augmente sur votre cible la plus lente.

Dans Three.js, inspectez renderer.info.render.calls, les triangles et les points pendant les parcours que les gens utilisent réellement. Un nombre d'appels plus bas n'est utile que si les matériaux, le travail des nuanceurs et la mémoire qui en résultent conviennent à l'appareil.

2. Compresser les textures pour le transfert et pour la mémoire du GPU

Le travail sur les textures améliore souvent à la fois le chargement et le rendu. Utilisez des images sources de taille appropriée, des mipmaps pour les textures observées à différentes échelles et des formats compressés pour GPU plutôt que d'envoyer de grandes images non compressées à chaque téléphone.

KTX2 avec Basis Universal est une voie de livraison solide pour un pipeline d'actifs multiappareil. MDN explique que Basis Universal peut convertir vers des formats de texture compressés courants au chargement. Le navigateur a tout de même besoin d'un format GPU pris en charge; testez donc le transcodeur et sa solution de repli sur de vrais appareils.

Ne compressez pas toutes les cartes de la même façon. Les cartes de couleur acceptent plus facilement un format avec perte que les données de normales, de rugosité ou de coordonnées. Une texture qui semble petite sur le réseau peut tout de même consommer beaucoup de mémoire GPU après le téléversement.

Les mipmaps ajoutent environ 33 % de surcharge de mémoire pour les textures carrées, selon les bonnes pratiques WebGL de MDN. Ce coût vaut souvent la peine pour une texture fréquemment observée de loin. Omettez les mipmaps pour une ressource qui n'est jamais réduite, et confirmez le résultat avec un profil de mémoire.

3. Charger les actifs à faible détail avant la scène finale

Le chargement progressif rend la page utile plus tôt et évite de demander à un téléphone de décoder toute l'expérience d'un coup. Commencez par une affiche, un petit modèle ou un maillage à faible détail. Remplacez-le par un actif de niveau de détail (LOD) supérieur après la première interaction ou lorsque l'actif est près de la caméra.

Divisez la scène en parcours ou en zones de caméra. Chargez seulement la géométrie, les textures, les animations et les cartes d'environnement nécessaires à la zone courante. Libérez les objets lorsqu'une zone n'est plus utilisée. Supprimer une référence JavaScript ne suffit pas si le moteur de rendu détient encore des ressources de géométrie, de matériau, de texture ou de cible de rendu.

Gardez la première action utile indépendante de la scène complète. Un utilisateur devrait pouvoir lire le titre, ouvrir le menu ou atteindre la section suivante pendant que les actifs 3D continuent de se charger. C'est une meilleure solution de repli qu'un canevas vide avec un indicateur de chargement.

4. Plafonner la résolution de rendu et le ratio de pixels

Les écrans mobiles peuvent amener un moteur de rendu à produire beaucoup plus de pixels que la mise en page n'en a besoin. Définissez un plafond de ratio de pixels et abaissez-le lorsque le temps de rendu dépasse votre budget. Gardez la taille CSS du canevas distincte de la taille de son tampon de dessin afin de pouvoir sacrifier de la netteté pour une interaction stable.

MDN recommande de dessiner dans un tampon arrière plus petit comme compromis simple entre qualité et vitesse. Ne multipliez pas le canevas par devicePixelRatio sans plafond en supposant que le résultat est sûr. Les écrans à haute densité peuvent transformer un effet par ailleurs modeste en une importante charge de fragments.

Redimensionnez à partir de la taille réelle en pixels de l'appareil lorsque le navigateur prend en charge device-pixel-content-box, et mettez à jour la fenêtre d'affichage avant de dessiner. Les directives WebGL de MDN indiquent que changer la taille du canevas l'efface; coordonnez donc le redimensionnement avec la boucle de rendu.

5. Alléger le travail de la boucle d'images

Utilisez requestAnimationFrame() pour les mises à jour visuelles et basez la fonction de rappel sur le temps. MDN note que les fonctions de rappel suivent généralement la fréquence de rafraîchissement de l'écran et prévient que l'animation s'exécute plus vite sur les écrans à rafraîchissement élevé lorsque le code ignore l'horodatage de la fonction de rappel.

Mettez le rendu en pause lorsque la page est masquée ou que la scène est hors de la zone visible. MDN précise que les navigateurs mettent en pause la plupart des fonctions de rappel requestAnimationFrame() dans les onglets en arrière-plan, mais votre propre logique de visibilité et d'intersection devrait tout de même arrêter le travail sur les actifs, la physique et le traitement des entrées.

Sortez le travail coûteux du chemin critique. Évitez les requêtes WebGL synchrones comme les appels répétés à getError(), getParameter(), les vérifications d'état des nuanceurs et les lectures par le CPU pendant l'interaction. MDN énumère ces appels comme des blocages synchrones possibles. Recueillez les diagnostics en développement, puis retirez-les ou limitez-les en production.

Utilisez moins de lumières, des chaînes de post-traitement plus courtes et des nuanceurs de fragments plus simples sur les petits écrans. Le travail effectué par fragment peut se multiplier sur l'ensemble du tampon de dessin; réduire à la fois la résolution et le coût des nuanceurs est donc plus efficace que d'en modifier un seul.

6. Bâtir des paliers de qualité et une vraie solution de repli

Utilisez la détection des capacités et un court échauffement, et non une liste noire de noms d'appareils. Choisissez un palier de qualité selon les fonctions WebGL disponibles, la prise en charge des textures, la taille de l'écran, le temps de rendu mesuré et la pression sur la mémoire. Laissez les utilisateurs passer à un palier inférieur et mémorisez ce choix pour la prochaine visite.

Un modèle de paliers utile ressemble à ceci :

Palier Choix de scène Choix d'interaction
Élevé Matériaux complets, ombres, post-traitement, LOD supérieur Mouvement continu de la caméra et du pointeur
Moyen Moins de lumières, tampon arrière plus petit, ombres simplifiées Effets réduits et mouvement plafonné
Faible Un modèle léger ou un rendu statique Le toucher et le défilement demeurent pleinement utilisables
Repli Affiche, vidéo ou composition HTML Aucune dépendance à WebGL

La solution de repli fait partie du design, ce n'est pas un écran d'erreur. MDN recommande de vérifier la disponibilité des extensions et de s'adapter lorsqu'une extension est absente. Appliquez la même logique à WebGL lui-même, aux pertes de contexte, aux téléchargements échoués et aux préférences de mouvement réduit.

7. Tester avec des données de terrain et des traces reproductibles

Exécutez un parcours de test reproductible sur chaque appareil visé : chargement à froid, premier contenu utile, première interaction avec la scène, mouvement de caméra soutenu, défilement dans la section la plus lourde, passage en arrière-plan et retour, puis rechargement à partir du cache. Capturez une trace de performance et conservez les mesures de la scène à côté.

Comparez les données d'utilisateurs réels avec les données de laboratoire. web.dev explique que CrUX et la surveillance des utilisateurs réels montrent ce que vivent les visiteurs, tandis que Lighthouse aide à diagnostiquer les causes. Un score Lighthouse sur ordinateur de bureau ne prouve pas qu'un GPU mobile peut soutenir la même scène.

Fixez des seuils d'acceptation avant la revue. Par exemple, vous pourriez exiger l'absence de pertes d'images visibles pendant l'interaction principale, l'absence de perte de contexte pendant un parcours de dix minutes, un tampon de dessin plafonné sur les appareils de palier faible et une solution de repli HTML utile lorsque WebGL échoue. Ce sont des décisions de projet, et non des limites universelles de WebGL; consignez donc l'appareil et les conditions de test avec chaque résultat.

Sources et références

Questions fréquentes

Quelle est la façon la plus rapide d'améliorer la performance WebGL sur mobile?

Réduisez d'abord la charge de dessin : regroupez les objets répétés, abaissez la résolution de rendu, simplifiez les nuanceurs de fragments et supprimez le travail effectué hors de la zone visible. Analysez ensuite la mémoire des textures et le chargement, car une scène peut être limitée par le GPU pendant l'interaction et par le réseau au démarrage. Mesurez l'interaction la plus lourde sur un vrai téléphone avant de choisir la prochaine correction.

Comment optimiser les textures WebGL pour le mobile?

Redimensionnez les textures à la plus grande taille dont l'objet a besoin sur l'écran visé, utilisez des mipmaps lorsque la texture est observée à différentes échelles et livrez des formats compressés pour GPU comme KTX2 avec Basis Universal lorsque le pipeline les prend en charge. Testez séparément les cartes de couleur, de normales et de données, car leurs besoins de qualité diffèrent.

Devrais-je utiliser un ratio de pixels d'appareil plus bas pour un site web 3D?

Oui, un ratio de pixels plafonné ou adaptatif est souvent le compromis de qualité le plus simple. Commencez avec un plafond prudent, surveillez le temps de rendu des images pendant l'interaction la plus lourde et abaissez la résolution du tampon de dessin lorsque l'appareil ne peut pas soutenir le palier choisi. Gardez la taille CSS du canevas inchangée pour que la mise en page ne saute pas.

Le regroupement rend-il toujours une scène WebGL plus rapide?

Non. Le regroupement peut réduire les changements d'état et la surcharge des appels de rendu, mais un grand lot peut augmenter le coût en nuanceurs, en surdessin ou en mémoire. Mesurez ensemble les appels, les triangles, le travail de fragments et le temps de rendu sur des téléphones représentatifs avant de conserver la modification. Un nombre d'appels plus bas n'est pas un gain utile si l'image rate encore son budget d'interaction.

Comment gérer les téléphones à faible puissance qui ne peuvent pas exécuter la scène complète?

Offrez un palier de qualité inférieur ou une solution de repli sans WebGL qui préserve le message de la page et son action principale. Gardez les titres, la navigation, le contenu et les commandes en HTML pour que l'expérience reste utilisable même lorsque le GPU, le navigateur ou la connexion ne peut pas prendre en charge la scène complète.

Comment tester de façon fiable la performance WebGL sur mobile?

Utilisez un parcours reproductible sur de vrais appareils, y compris le chargement à froid, l'interaction avec la scène, le défilement, la mise en arrière-plan et le rechargement à partir du cache. Jumelez une trace du navigateur à des données de terrain comme CrUX ou votre propre surveillance des utilisateurs réels, et conservez l'appareil, le navigateur, la connexion, le ratio de pixels et les mesures de la scène pour chaque essai.

Travaillons ensemble

Prêts à faire passer votre marque au niveau supérieur? Parlez-nous de votre projet.

Démarrer un projet