Plateforme

navigator.hardwareConcurrency et planification des Web Workers

Comprendre navigator.hardwareConcurrency, choisir la taille d’un groupe de Web Workers et tester la concurrence sans confondre une indication du navigateur avec le nombre de cœurs.

Documentation

Vous voulez la documentation structurée pour Plateforme ?

Cet article fait partie de la bibliothèque éditoriale. Pour les étapes de configuration, la référence et les mises à jour continues, passez directement à la section docs.

navigator.hardwareConcurrency est une indication de concurrence fournie par le navigateur, pas la promesse qu’une page peut exécuter autant de tâches simultanément. Utilisez-la comme une entrée d’une politique de groupe de Workers bornée, puis mesurez l’attente en file, le temps de fin, la pression mémoire et la réactivité. Une bonne planification s’arrête avant que de nouveaux Workers n’ajoutent surtout de la contention.

Schéma d’une indication de concurrence alimentant un groupe de Workers borné

La valeur correspond au nombre de processeurs logiques exposés à la page, et le navigateur peut la réduire pour limiter la concurrence. Le guide sur l’appareil et la fenêtre d’affichage montre une autre limite : une valeur exposée par le navigateur sert à la compatibilité, elle ne décrit pas tout l’appareil.

Ce que signifie la valeur

La référence MDN de Navigator.hardwareConcurrency définit le nombre de processeurs logiques disponibles pour exécuter des threads sur l’ordinateur de l’utilisateur. Elle précise aussi que le navigateur peut en déclarer moins que la machine n’en possède. La valeur convient donc comme estimation de départ, mais ne prouve ni le nombre de cœurs physiques, ni la charge CPU actuelle, ni la mémoire disponible pour la page.

La propriété se lit sur navigator dans une fenêtre et dans la portée globale d’un Worker. Elle ne crée pas de threads, ne réserve pas de temps CPU et ne rend pas une tâche parallèle. Un Worker communique toujours par messages, et la page paie toujours les coûts de sérialisation, de planification, d’allocation et de synchronisation.

Considérez les changements comme des événements normaux de compatibilité. Une autre version du navigateur, une politique du système d’exploitation, un mode d’alimentation, un réglage de confidentialité ou un contexte différent peuvent exposer une autre indication. N’utilisez pas ce nombre comme signal d’identité, décision d’autorisation ou raison de collecter un profil matériel plus détaillé.

Transformer l’indication en politique de Workers

Commencez par un petit groupe et une file. Pour des tâches indépendantes limitées par le CPU, le plafond initial ne devrait pas dépasser l’indication et doit souvent être inférieur. Réservez des ressources pour la page, les entrées, le réseau, le rendu et le système d’exploitation. Pour des tâches limitées par les entrées-sorties, moins de Workers peuvent suffire puisqu’ils attendent souvent.

Le modèle des Workers WHATWG définit les Workers comme des contextes d’exécution séparés qui communiquent avec leur créateur par messages. Cette limite rend la file essentielle : envoyez des lots bornés, transférez les grands tampons quand cela convient et définissez le comportement en cas d’annulation ou d’échec d’un Worker. Le groupe doit pouvoir cesser d’accepter du travail au lieu de croître sans limite.

Utilisez une politique telle que min(availableHint, configuredMaximum) plutôt que de copier directement l’indication comme taille du groupe. Définissez un maximum distinct pour les mobiles ou les contextes à mémoire réduite, et laissez la limite de l’application primer lorsque le coût de la tâche est connu. Le maximum configuré est une décision produit ; l’indication du navigateur n’est qu’une entrée.

Mesurer la saturation et la réactivité

Testez la tâche réelle, pas une boucle vide. Mesurez l’attente en file, le temps d’exécution, la fin de bout en bout, les tâches échouées ou annulées, la mémoire et la réactivité du thread principal. Comparez un Worker, un petit groupe et des groupes plus grands avec des données représentatives. Cessez d’augmenter la concurrence lorsque le débit plafonne ou que la latence, la mémoire ou l’interaction se dégradent.

Séparez les essais à froid et à chaud. Le démarrage du Worker et le chargement du script peuvent dominer une tâche courte, tandis qu’un flux long peut être limité par le calcul ou le transfert de messages. Notez la version du navigateur, la taille d’entrée, la classe d’appareil et l’état d’alimentation pour comparer les résultats. Ne déduisez pas la topologie physique de la machine à partir des seuls temps.

Testez aussi les échecs. Un Worker arrêté, un message refusé, une erreur de mémoire ou un changement de visibilité de la page doit renvoyer le travail vers une file bornée ou un état d’erreur explicite. L’annulation doit libérer les tampons et retirer la tâche des mesures. Limitez les nouvelles tentatives afin qu’une tâche en échec ne sature pas le groupe.

Préserver les limites de confidentialité et de compatibilité

L’indication est volontairement approximative et peut être réduite. La page doit fonctionner si elle manque, est faible ou diffère d’une observation précédente. Détectez le support des Workers et prévoyez une solution sur le thread principal ou séquentielle pour les tâches courtes. Ne combinez pas hardwareConcurrency avec des mesures de temps, de graphisme, de police ou de stockage pour identifier une personne ou un appareil.

Expliquez le choix de ressources lorsqu’il affecte la batterie, les données ou un envoi. Un groupe local de Workers n’autorise pas l’envoi de données ailleurs. Si un flux passe du traitement local à un service distant, demandez un choix explicite et indiquez quelles données quittent l’appareil. Ne conservez dans les journaux que les mesures nécessaires à la file, sans contenu brut ni détails matériels inutiles.

Classer le travail avant de choisir le groupe

Le nombre de Workers est plus facile à choisir lorsque le travail est bien défini. Une transformation limitée par le CPU peut profiter de plusieurs Workers jusqu’à occuper le processeur. Une tâche limitée par le réseau attend souvent une réponse, donc ajouter des Workers peut augmenter la pression sans améliorer la page. Une tâche qui partage un état peut nécessiter moins de Workers, car la coordination est la limite.

Séparez le travail indépendant du travail ordonné. Les éléments indépendants peuvent finir dans n’importe quel ordre et retrouver l’ordre d’affichage grâce à un numéro de séquence. Les étapes ordonnées doivent garder leurs dépendances explicites au lieu de créer un Worker par étape. Définissez l’unité mesurée avec préparation, transfert, exécution, résultat et nettoyage.

Concevoir le cycle de vie de la file

Une file bornée a besoin de règles d’admission, d’exécution et de fin. L’admission peut refuser un travail, remplacer une mise à jour ou afficher une progression quand la limite est atteinte. L’exécution marque le travail actif et prévoit une annulation ou un délai. La fin libère le Worker, règle le travail une seule fois et actualise les mesures.

La contre-pression fait partie de l’expérience. Si l’utilisateur sélectionne plus de fichiers que la page ne peut traiter, indiquez s’ils attendent, sont abandonnés ou passent après les précédents. Ne faites pas croître silencieusement une liste illimitée. Une limite protège la mémoire et rend l’annulation prévisible.

Un seul composant doit posséder l’état de la file. La page peut gérer l’admission et l’ordre, tandis que chaque Worker ne gère que sa tâche. Les messages portent un identifiant et les données nécessaires ; les réponses indiquent réussite, échec ou annulation. Un résultat tardif reste alors inoffensif si l’utilisateur a remplacé la tâche.

Compter les coûts de transfert et de mémoire

Le parallélisme ne supprime pas le déplacement des données. Le clonage structuré peut copier des objets, tandis que les tampons transférables déplacent la propriété quand l’API le permet. Mesurez les deux choix avec des charges représentatives. Un groupe qui copie pendant la plupart du temps n’est pas plus rapide pour l’utilisateur.

Limitez les charges et libérez les références après la fin. Les données gardées par la page, la file et un Worker peuvent multiplier la mémoire. Lors d’une annulation, supprimez la charge en attente et arrêtez le Worker si possible. Une allocation impossible est une erreur normale, pas une raison d’agrandir le groupe.

Les résultats ont aussi une politique de conservation. Affichez seulement ce qui est nécessaire, paginez les grandes listes et évitez les copies en double. Si un résultat est mis en cache, définissez sa durée et son invalidation. Ces choix améliorent souvent la réactivité plus qu’un Worker supplémentaire.

Adapter le travail à la visibilité et à l’énergie

Une page masquée peut subir d’autres contraintes de planification et d’énergie. Suspendez le travail non essentiel quand le document est masqué, ou réduisez sa priorité et laissez la file se vider. Au retour, vérifiez que les tâches restent utiles, car une recherche ou un aperçu a pu changer.

Sur mobile, un groupe soutenu peut consommer la batterie et produire de la chaleur. Proposez un mode qui privilégie réactivité et autonomie pour le travail interactif ou en arrière-plan. Ce mode change le maximum configuré, pas l’interprétation de l’indication comme mesure de batterie.

N’utilisez pas la visibilité ou l’énergie comme signal d’identité. Ce sont des entrées opérationnelles qui changent pendant la session. Gardez la décision locale et n’envoyez pas ces observations sans choix explicite.

Rendre le repli observable

Détectez la capacité au point d’utilisation. Vérifiez le constructeur Worker et la messagerie requise, puis prévoyez un chemin séquentiel lorsque l’un manque. Ce chemin peut traiter un élément à la fois, céder entre blocs ou demander un nouvel essai, avec le même format de résultat et l’annulation si possible.

Montrez des états utiles sans détails internes : préparation, traitement, pause ou échec. Proposez une nouvelle tentative seulement si elle peut changer l’issue et rendez l’échec permanent compréhensible. Un nombre de Workers n’est pas une promesse de vitesse.

Testez un Worker arrêté, un résultat invalide, un délai, une annulation pendant le transfert et une navigation. Chaque cas doit régler son travail, libérer ses ressources et laisser les autres utilisables. Une tâche défectueuse ne doit pas bloquer la file.

Lire les mesures comme des décisions

Les résultats répondent à une question limitée : pour cette charge, cette taille, ce navigateur et cette classe d’appareil, quelle politique équilibre correctement les besoins ? Ils ne donnent pas une taille universelle. Gardez une matrice représentative et répétez les essais pour distinguer le bruit de démarrage.

Comparez les distributions, pas seulement les moyennes. Le percentile lent, les annulations, le pic mémoire et les longues tâches du thread principal peuvent révéler une régression. Notez l’indication, le maximum, la version du script et l’essai à froid ou à chaud.

Transformez le résultat en politique réversible. Commencez prudemment, limitez les contextes contraints et changez le plafond seulement avec de nouvelles mesures. Si le travail change, mesurez encore. L’indication reste approximative même si un essai correspond aux processeurs physiques.

Pour exploiter la file, mesurez sa longueur, les annulations et la latence de bout en bout. Ne conservez pas les entrées brutes ni des détails matériels inutiles.

Sources publiques

Pour les décisions liées aux capacités du navigateur, consultez le guide de cohérence WebAssembly et le guide de planification de capacité des contextes. Gardez ces mesures opérationnelles séparées de l’indication de concurrence du navigateur.

#hardwareConcurrency#Web Workers#Performances Du Navigateur#Concurrence

Faites passer BotBrowser de la recherche à la production

Utilisez ces guides pour comprendre le modèle, puis passez à la validation multi-plateforme, aux contextes isolés et au déploiement navigateur prêt pour l'échelle.