Sur un ordinateur de développement, un nouveau sélecteur semble instantané. Sur un mobile moins puissant, la même ouverture attend la fin d’un bundle, d’une initialisation analytique et d’un calcul de variantes. Le réseau a livré la page ; pourtant le bouton ne répond pas.
Le vrai enjeu du budget JavaScript mobile consiste à réserver du temps de processeur aux interactions importantes, pas seulement à plafonner des octets. Un fichier compressé modeste peut déclencher beaucoup d’analyse et d’exécution, tandis qu’un module plus gros mais différé ne gêne aucun parcours initial.
L’équipe doit donc suivre quatre monnaies : transfert, taille décodée, travail du thread principal et code réellement utilisé. Elle les segmente par gabarit, appareil et étape du parcours, puis fait porter chaque dépassement à la fonctionnalité qui l’introduit.
Un audit de performance et de SEO technique transforme ces traces en décisions de produit, de frontend et de livraison. La méthode suivante fixe des seuils locaux sans présenter un chiffre fictif comme une norme du Web.
Comprendre pourquoi un kilooctet JavaScript coûte plusieurs fois
Suivre tout le cycle de la ressource
Le navigateur télécharge, décompresse, analyse, compile puis exécute le code. La documentation web.dev sur la réduction des charges JavaScript insiste sur cette différence avec une image, dont le coût de décodage reste généralement moins complexe. Le transfert ne suffit donc pas à prédire la disponibilité de l’interface.
Le rapport conserve taille compressée, taille non compressée, temps d’évaluation et fonctions chaudes. Il distingue initialisation, rendu et travail après interaction. Une moyenne agrégée effacerait précisément le goulot d’étranglement recherché.
Lire le coût marginal d’une fonctionnalité
Une bibliothèque déjà présente ne coûte pas zéro lorsqu’une nouvelle option augmente son exécution. À l’inverse, un module chargé à la demande n’est pas facturé au démarrage, mais rejoint le budget de l’interaction qui l’appelle. Le dossier suit le parcours, pas seulement la liste des fichiers.
Le coût caché apparaît aussi dans les mises à jour : dépendance vulnérable, polyfill devenu inutile, incompatibilité de framework et temps de test. La décision produit doit connaître cette dette avant de retenir la solution la plus rapide à intégrer.
Choisir des mobiles et des cohortes qui révèlent la dette
Éviter le mobile abstrait
Le protocole choisit un appareil cible à partir de l’audience, puis un appareil plus contraint pour la borne de risque. Il fixe navigateur, température, mode d’économie, réseau et état du cache. Une simple limitation CPU dans un poste puissant aide à comparer, mais ne reproduit pas toute la mémoire et la dissipation thermique d’un téléphone.
Les mesures sont répétées après refroidissement et avec un profil propre. L’équipe conserve médiane et dispersion. Une valeur isolée peut refléter une tâche du système, une compilation froide ou une ressource tierce variable.
Segmenter selon l’usage
Le démarrage anonyme, le retour avec cache, la session connectée et l’arrivée après consentement déclenchent des graphes différents. La recherche, les filtres, le panier et l’espace client ne partagent pas non plus les mêmes priorités. Chaque budget protège une étape où l’utilisateur attend réellement une réponse.
Un premier signal faible survient lorsque les octets restent stables mais que le temps CPU augmente sur une release. La cause peut être une nouvelle configuration, davantage de données ou une boucle exécutée plus souvent. Le diff de bundle seul ne la verra pas.
Attribuer bundles, modules et tiers aux parcours
Construire une carte de propriété
Chaque chunk reçoit une origine, des routes consommatrices, une condition de chargement et un responsable. Le socle, le gabarit et la fonctionnalité sont séparés. Le code commun ne devient pas une zone sans propriétaire simplement parce que plusieurs équipes l’utilisent.
La carte rapproche graphe de build, couverture Chrome et trace Performance. Le graphe dit ce qui pourrait charger ; le réseau dit ce qui charge ; la couverture indique ce qui s’exécute ou reste inutilisé pendant le scénario. Ces preuves répondent à des questions différentes.
Traquer les doublons sémantiques
Deux versions d’une utilité, plusieurs bibliothèques de dates ou des composants aux fonctions proches gonflent le décodage. Les noms de fichiers hachés masquent parfois cette duplication. Une analyse des dépendances et des exports la rend attribuable.
Le second signal faible est une multiplication de petits chunks initiaux. Leur somme semble acceptable, mais la coordination, les en-têtes et l’évaluation fragmentée prolongent le démarrage. La bonne réponse peut être regrouper certains modules, pas découper davantage.
Budgéter analyse, compilation et longues tâches
Compter les périodes réellement bloquantes
Une tâche supérieure à 50 ms est qualifiée de longue tâche dans le modèle présenté par web.dev sur l’optimisation du thread principal. La partie au-delà de 50 ms constitue sa période de blocage. Ce repère officiel décrit la métrique ; il ne fixe pas à lui seul le budget complet d’un produit.
Le contrôle suit nombre, durée totale, plus longue tâche et attribution des piles. Une seule tâche de 220 ms juste avant une interaction est plus urgente que quatre tâches de 60 ms exécutées lorsque l’écran est inactif.
Éviter le budget CPU global
Le temps principal est réparti entre évaluation initiale, hydratation, tiers, rendu et action métier. Le budget indique une fenêtre : avant le premier rendu, entre rendu et disponibilité, puis lors d’une interaction choisie. Additionner toute la session pénaliserait une utilisation longue sans expliquer l’attente.
La trace conserve les fonctions dominantes et les données d’entrée. Un calcul peut devenir lent uniquement avec 200 variantes ou un panier important. La fixture doit représenter cette borne métier réaliste.
Protéger les interactions au-delà du démarrage
Choisir des gestes sentinelles
L’ouverture du menu, l’application d’un filtre, l’ajout au panier et la validation d’un formulaire couvrent des architectures différentes. Chaque geste sentinelle possède un état de départ, une action automatisée et un résultat visuel attendu. Le budget associe latence et travail JavaScript attribuable.
INP terrain complète la recette, mais la CI a besoin d’un scénario déterministe. Elle mesure délai d’entrée, traitement des gestionnaires et présentation suivante. Un bon résultat de démarrage ne compense pas une interaction centrale bloquée.
Découper sans retarder le résultat
La page officielle explique comment rendre la main avec des tâches plus petites. Pourtant, découper mécaniquement peut retarder l’achèvement ou créer des états intermédiaires. Le travail visible, validation et mise à jour de l’interface passent avant l’analytique et les traitements secondaires.
Contre-intuitivement, ajouter un point de suspension n’est pas toujours bénéfique. Des tâches déjà très courtes paieraient le coût de planification sans réduire une attente perceptible. Le profileur doit montrer où le thread manque réellement d’occasions de répondre.
Décider ce qui doit charger maintenant, plus tard ou jamais
Classer par nécessité et probabilité
Le code indispensable au rendu et à l’action principale charge tôt. Le code probable peut être préchargé avec prudence après les ressources critiques. Le code rare attend l’intention ou l’action. Le code inutilisé est supprimé plutôt que différé.
Cette classification s’appuie sur taux d’usage et coût d’attente. Précharger chaque route potentielle recrée un bundle global sous une autre forme. À l’inverse, charger un validateur seulement après le clic peut rendre le premier usage pénible.
Préserver l’échec et l’accessibilité
Un module différé peut échouer ou arriver tard. Le bouton garde un état compréhensible, une relance et un suivi d’erreur. Le HTML essentiel et les liens restent utilisables lorsque JavaScript ne répond pas, selon le contrat du produit.
Le budget vérifie aussi l’effet sur le réseau. Multiplier les imports dynamiques peut créer une chaîne découverte après interaction. Le gain initial ne doit pas devenir une cascade qui bloque la tâche suivante.
Tester un budget interne avec un cas explicitement simulé
Donner des nombres pour illustrer, pas pour normaliser
Cas entièrement simulé. Par exemple, une équipe mesure sur son appareil cible une page catégorie avec 210 Ko de JavaScript initial compressé, 640 ms de travail principal au démarrage et trois longues tâches, dont une à 145 ms. Elle fixe localement une alerte à 220 Ko et un plafond à 235 Ko, puis demande qu’aucune nouvelle tâche ne dépasse 150 ms.
Ces seuils fictifs ne sont ni une norme Chrome, ni une recommandation universelle. Ils servent à montrer la combinaison d’une enveloppe réseau, d’un coût CPU et d’une borne de tâche, déterminée à partir d’une baseline locale.
Arbitrer la fonctionnalité simulée
Un nouveau filtre ajoute 18 Ko et une tâche de 70 ms. Le total reste sous le plafond, mais la tâche s’ajoute juste avant la présentation du résultat. L’équipe sépare le calcul, rend le résultat principal, puis diffère l’analytique. Le poids ne change presque pas ; l’interaction devient disponible plus tôt.
Si la correction ne suffit pas, trois options restent : charger le filtre à l’intention, remplacer la bibliothèque ou simplifier la règle métier. Augmenter le plafond arrive en dernier et exige une preuve d’usage.
Construire un contrôle déterministe dans la CI
Croiser manifeste et trace navigateur
Le build compare les tailles par point d’entrée et signale exports, dépendances ou chunks responsables. Un navigateur exécute ensuite les gestes sentinelles sur appareil simulé constant. Les artefacts comprennent réseau, trace CPU, couverture et version.
La CI utilise plusieurs répétitions et une règle stable. Une régression absolue bloque ; une hausse proche de l’alerte demande une revue. Le commentaire indique la différence plutôt qu’un score global.
Conserver une commande de reproduction
Le développeur doit pouvoir lancer le même scénario avec les mêmes données. Les tiers variables sont simulés ou épinglés. Une mesure trop instable ne devient pas un gate : l’équipe corrige d’abord le protocole.
Le mécanisme de repli rétablit le dernier chunk sain ou désactive la fonctionnalité par configuration. La livraison canari vérifie les erreurs et INP avant extension. Le budget s’insère ainsi dans une décision, pas dans un rapport oublié.
Les responsabilités séparent le propriétaire du bundle, la QA mobile et le release manager ; les dépendances, seuils et traces de journalisation restent attachés à la version déployée.
Le runbook associe monitoring des longues tâches, contrat de repli et seuil d’arrêt ; cette traçabilité autorise un rollback avant que la file du thread principal ne dégrade toute la cohorte.
Faire porter leur coût aux scripts tiers
Créer un registre de valeur et de charge
Chaque tag possède finalité, équipe demandeuse, routes, consentement, taille, travail principal et date de revue. Le chargement conditionnel est testé. Une balise présente dans le gestionnaire mais jamais utile sur une route ne doit pas consommer son budget.
La page web.dev sur le JavaScript tiers décrit notamment l’usage de async et defer. Ces attributs protègent l’analyse HTML, mais n’annulent pas l’exécution ultérieure sur le thread principal.
Prévoir indisponibilité et dérive
Le fournisseur peut modifier son code sans release du site. Une surveillance mesure ses octets et longues tâches en production. Un plafond propre aux tiers évite qu’une dérive soit attribuée au bundle applicatif.
Le tiers non essentiel se charge après consentement et période critique. S’il échoue, le parcours continue. Une façade légère remplace un widget lorsque la valeur n’apparaît qu’après intention.
Accepter une exception sans perdre la trajectoire
Documenter une dette mesurable
L’exception nomme module, scénario, surcoût réseau, surcoût CPU, raison, responsable, date d’expiration et retrait prévu. Elle ne relève pas automatiquement le budget. Le test continue d’afficher la dette à chaque branche.
Une expérimentation peut obtenir une fenêtre courte si elle isole sa cohorte et possède un interrupteur. Le résultat business est comparé au coût. Sans usage ou conversion démontrée, le code est retiré.
Réviser le seuil seulement si le produit change
Une application qui devient configurateur peut nécessiter davantage de calcul. Le nouveau contrat compare rendu serveur, worker, traitement progressif et simplification. La décision explique pourquoi le CPU supplémentaire est indispensable.
Une exception renouvelée trois fois révèle un choix d’architecture ou de gouvernance. Elle remonte au produit et à la direction technique au lieu de rester un commentaire de pipeline.
Pour qui arbitrer dette produit et conversion
Prioriser par surface et réversibilité
Le premier travail supprime code inutilisé et doublons sur toutes les routes. Viennent ensuite les tâches longues des gestes essentiels, puis le chargement tardif des fonctions rares. Une refonte lourde se justifie seulement si les profils montrent une limite structurelle.
L’impact croise volume mobile, latence, taux d’usage, conversion, coût de correction et risque. Une optimisation de 100 ms sur le paiement peut valoir davantage qu’un gain de 300 ms dans un écran rarement ouvert.
Décider sans ambiguïté
- Conserver : usage prouvé, coût sous budget et comportement stable.
- Différer : fonction utile mais absente du parcours initial.
- Remplacer : valeur réelle, implémentation disproportionnée ou trop bloquante.
- Supprimer : code sans usage, responsable ou résultat mesuré.
Le dossier attache le profil avant et après. Une baisse d’octets sans baisse de CPU n’est pas présentée comme une victoire complète ; une baisse CPU sans variation de poids reste au contraire un gain valable.
Éviter les faux gains de découpage et de différé
Déplacer le coût hors de la mesure
Déclencher un script juste après l’arrêt de la trace, exclure les tiers ou mesurer une page sans données améliore artificiellement le rapport. Le scénario doit aller jusqu’au résultat métier et inclure les états réels.
Le lazy loading généralisé peut créer une attente à chaque geste. Il protège le démarrage, mais dégrade l’usage. Les modules probables sont préparés après les ressources critiques et avant l’intention, seulement lorsque les données d’usage le justifient.
Confondre taille et architecture
Remplacer une dépendance n’efface pas une boucle coûteuse, des données excessives ou un rendu répété. Le profileur identifie la fonction et son déclencheur. L’optimisation agit sur la cause avant de changer d’outil.
Un budget trop sévère génère des contournements ; un budget uniquement en octets laisse passer les régressions CPU. La combinaison doit rester assez petite pour être comprise et assez complète pour protéger l’utilisateur.
Plan d’action : reprendre le contrôle en six étapes
Mesurer avant de couper
La première étape choisit appareils, routes et gestes sentinelles. La deuxième produit manifestes, couverture et traces. La troisième attribue le socle, les fonctions et les tiers. Aucune limite n’est fixée avant cette carte.
La quatrième définit alertes et plafonds sur transfert, travail initial et tâches d’interaction. Elle rejoue une dépendance ajoutée, un tiers lent et une donnée volumineuse pour tester la sensibilité du contrôle.
Installer la décision et son suivi
La cinquième étape branche le diff de build et les traces dans la CI, avec commande de reproduction et artefacts. La sixième déploie un canari, annote la version et suit INP, erreurs et usage par cohorte mobile.
Après quatre semaines, la revue retire les exceptions expirées et compare la dette au plan produit. Les seuils évoluent seulement avec de nouvelles preuves. Le registre garde la raison de chaque arbitrage.
- Choisir un appareil et des interactions représentatives.
- Attribuer chaque coût à un module ou à un tiers.
- Bloquer les régressions reproductibles, pas le bruit.
- Confirmer le résultat sur les cohortes mobiles réelles.
Formaliser le contrat remis à chaque équipe
La fiche de budget contient le point d’entrée, les chunks initiaux, l’appareil de référence, les gestes sentinelles, les valeurs d’alerte, les plafonds et la commande de reproduction. Elle précise aussi la méthode de calcul : compression retenue, fenêtre de trace, nombre d’exécutions et façon d’agréger. Une équipe ne doit pas deviner si le temps CPU couvre seulement l’évaluation ou toute l’interaction.
Pour chaque dépassement, le formulaire exige l’export ajouté, la fonctionnalité bénéficiaire, le pourcentage d’utilisateurs concernés et l’option de repli. Le responsable du socle valide une hausse du commun ; le responsable produit valide la valeur ; le release manager conserve le droit d’arrêter la diffusion. Cette répartition empêche qu’un gain local impose sans discussion du JavaScript à toutes les routes.
La revue trimestrielle recherche les modules qui ne sont plus appelés, les expériences terminées et les appareils dont la part d’audience a changé. Elle compare aussi le temps d’analyse à la taille : un rapport qui se dégrade à octets constants signale souvent davantage d’exécution, des objets plus volumineux ou une dépendance dont la nouvelle version travaille différemment.
Lorsqu’une correction retire du code, le test vérifie le parcours de secours, les erreurs et l’accessibilité. Un module mort peut cacher une branche encore utilisée par une langue, un rôle ou un ancien navigateur. La couverture guide l’enquête, mais seule une recette fonctionnelle autorise la suppression. Le budget reste ainsi un outil de réduction de dette sans devenir une machine à casser des cas rares.
Relier JavaScript, rendu et Core Web Vitals
Compléter l’enquête technique
La maîtrise du rendu JavaScript, SSR et ISR aide à placer le travail entre serveur, HTML initial et hydratation. Cette frontière modifie directement le budget mobile.
Le pilotage des Core Web Vitals relie les gestes sentinelles aux distributions terrain. Il empêche de conclure depuis une seule trace de laboratoire.
Garder les preuves minimales
Un budget durable conserve manifeste, trace, scénario et décision. Ce quatuor explique à la fois le poids, le CPU, le contexte et l’arbitrage.
La QA rapproche routes, logs de CI, cache, revalidation et HTML rendu ; elle vérifie aussi crawl, indexation et canonical lorsqu’un chargement client est déplacé.
- Manifeste et couverture sur mobile.
- Trace de l’interaction et version de route.
- Décision, seuil et preuve de rollback.
Conclusion : réserver le CPU aux usages qui comptent
Le mobile ne paie pas seulement le téléchargement du JavaScript. Il paie sa décompression, son analyse, son exécution et l’attente créée devant chaque interaction.
Un budget solide relie ces coûts à des routes, appareils et gestes. Il distingue le socle, la fonctionnalité et les tiers, puis refuse les déplacements comptables qui ne changent pas le navigateur.
Les seuils locaux, les exceptions datées et le suivi terrain rendent la dette visible sans figer le produit. Une fonctionnalité peut consommer de la marge si sa valeur et son mécanisme de repli sont prouvés.
Dawap peut vous accompagner pour construire ces scénarios, profiler les bundles et installer leur contrôle dans un audit de performance et de SEO technique.