Écrire une balise de script directement dans un gabarit fonctionne, jusqu'au jour où deux extensions chargent la même bibliothèque en deux versions différentes, où un script s'exécute avant celui dont il dépend, ou où le navigateur sert une version périmée après une mise en production. WordPress fournit un mécanisme de file d'attente des ressources qui résout ces trois problèmes en même temps, en centralisant les déclarations, en gérant les dépendances et en versionnant les adresses. Son emploi n'est pas une préférence de style : c'est ce qui permet à des dizaines de composants écrits par des gens différents de cohabiter sur une même page sans se marcher dessus.

Le mécanisme et ce qu'il règle

Comprendre ce que la file d'attente apporte explique pourquoi tout contournement se paie tôt ou tard. Le sujet touche directement au fichier de fonctions du thème, dont nous décrivons le rôle dans notre article sur le fichier functions.php de WordPress.

Déclarer plutôt qu'écrire

Le principe consiste à déclarer une ressource auprès du système, avec un identifiant, une adresse, ses dépendances, une version et son emplacement souhaité dans la page. WordPress rassemble ensuite l'ensemble des déclarations, résout les dépendances, ordonne les ressources et écrit les balises au bon endroit. Cette centralisation permet à un composant de dire qu'il a besoin d'une bibliothèque sans savoir si elle a déjà été demandée par un autre, ce qui est exactement le problème que pose une balise écrite en dur. Le mécanisme est ancien, stable et documenté, et il n'a pas changé dans ses principes depuis plus de dix ans.

La déduplication

Deux extensions demandant la même bibliothèque sous le même identifiant ne la chargent qu'une fois. C'est le bénéfice le plus immédiat et le plus visible : une page qui chargeait trois fois la même bibliothèque de trente kilooctets n'en charge plus qu'une. Cette déduplication repose entièrement sur l'emploi d'identifiants communs, ce qui explique pourquoi il faut employer les identifiants déjà connus du cœur pour les bibliothèques qu'il fournit, plutôt que d'en déclarer une copie sous un nom différent. La liste des bibliothèques fournies par le cœur est publiée et mérite d'être consultée avant d'en embarquer une copie.

L'ordre et les dépendances

Chaque déclaration liste les identifiants dont elle dépend, et le système garantit que ceux ci seront chargés avant. Un script qui dépend d'une bibliothèque n'a donc pas à s'inquiéter de sa position dans la page. Cette résolution automatique supprime la classe entière des erreurs signalant qu'une fonction n'existe pas, qui représentent une part considérable des incidents rencontrés sur les sites où les ressources sont écrites à la main dans les gabarits. Une dépendance déclarée coûte un mot dans un tableau et évite des heures de recherche.

La version et le cache du navigateur

Le paramètre de version est ajouté à l'adresse de la ressource, ce qui produit une adresse différente à chaque changement de version. Le navigateur considère alors qu'il s'agit d'une ressource nouvelle et la retélécharge, sans quoi il continuerait de servir l'ancienne pendant des jours. Omettre ce paramètre ou le laisser figé est la cause la plus fréquente des modifications de style invisibles après mise en production, incident qui fait perdre un temps considérable en diagnostic. Le symptôme est caractéristique : la modification est visible en navigation privée et invisible dans le navigateur habituel.

L'emplacement dans la page

Un script déclaré comme devant être chargé en pied de page ne bloque pas l'affichage du contenu, contrairement à un script placé dans l'en-tête. Cette différence est déterminante pour la vitesse perçue, le navigateur devant interrompre la construction de la page à chaque script rencontré. La règle par défaut consiste à tout charger en pied de page, l'en-tête étant réservé aux rares ressources dont l'absence produirait un affichage incorrect pendant le chargement. Les feuilles de style critiques et les scripts modifiant la mise en page très tôt relèvent de cette exception.

Ce que le mécanisme n'apporte pas

Il ne décide pas si une ressource est nécessaire, ne réduit pas son poids et ne résout pas les conflits entre deux versions incompatibles d'une même bibliothèque déclarées sous des identifiants différents. Ces trois questions relèvent de décisions humaines. Le mécanisme organise le chargement, il ne remplace pas la réflexion sur ce qui doit être chargé, et un site déclarant proprement quarante ressources inutiles reste un site lent. Le tri de ce qui est réellement nécessaire vient donc avant toute considération de méthode de déclaration.

Situation Pratique correcte Conséquence si négligé
Ajouter un script Déclaration dans la file d'attente Doublons et erreurs d'ordre
Bibliothèque fournie par le cœur Employer l'identifiant officiel Deux versions chargées
Dépendance entre scripts Déclarer la dépendance Fonction introuvable
Modification d'un fichier Changer le numéro de version Ancienne version servie
Ressource utile sur une page Chargement conditionnel Poids inutile partout
Passer des données au script Fonction de transmission dédiée Variables globales fragiles
Style du thème enfant Dépendance vers le parent Ordre des règles imprévisible
Organisation de la file d’attente des scripts et des feuilles de style

Écrire les déclarations correctement

Quelques règles suffisent à obtenir un chargement propre, et leur respect distingue immédiatement un thème sérieux d'un thème bricolé.

S'accrocher au bon moment

Les déclarations doivent être faites depuis le point d'entrée prévu pour cela, distinct pour le site public, pour l'administration et pour l'écran de connexion. Déclarer une ressource trop tôt produit un avertissement et un chargement incorrect, la déclarer trop tard la fait ignorer silencieusement. Une extension ajoutant ses ressources à l'administration doit également vérifier sur quel écran elle se trouve, faute de quoi elle alourdit l'ensemble du back office pour une page de réglages consultée trois fois par an. Le contexte de l'écran courant est fourni en paramètre du point d'entrée, ce qui rend ce test trivial à écrire.

Construire l'adresse proprement

L'adresse d'une ressource doit être construite avec les fonctions dédiées, qui renvoient le chemin du thème ou de l'extension quelle que soit l'installation. Écrire un chemin en dur casse le site dès qu'il est déplacé, renommé ou installé dans un sous répertoire, ce qui arrive à peu près toujours au moment le moins commode. Ces fonctions gèrent également le passage en connexion sécurisée et les installations en sous domaine, deux cas où un chemin écrit à la main échoue. Elles diffèrent selon qu'il s'agit d'un thème, d'un thème enfant ou d'une extension, distinction qu'il faut connaître une fois pour toutes.

Versionner avec la date du fichier

Plutôt qu'un numéro de version maintenu à la main, l'emploi de la date de dernière modification du fichier produit un versionnement automatique et toujours exact. La ressource change, l'adresse change, le navigateur retélécharge. Cette astuce tient en un appel de fonction et supprime définitivement les problèmes de cache navigateur pendant le développement comme après une mise en production, ce qui en fait probablement le conseil le plus rentable de tout le sujet. Sur un site en production, il faut simplement s'assurer que la date des fichiers change bien lors du déploiement, ce qui n'est pas garanti par toutes les méthodes de mise en ligne.

Transmettre des données au script

Un script a souvent besoin de valeurs calculées côté serveur : une adresse de point d'entrée, un jeton, une chaîne traduite. La fonction prévue pour cela ajoute un objet JavaScript avant le script concerné, ce qui évite d'écrire des variables globales dans le gabarit. Les versions récentes proposent une variante plus souple permettant d'ajouter du code avant ou après une ressource déclarée, mécanisme préférable dès qu'il s'agit d'autre chose que d'un simple objet de configuration. Les valeurs transmises doivent évidemment être encodées correctement, un nom contenant une apostrophe suffisant à casser le script.

Ne jamais écrire de balise à la main

Une balise de script écrite dans un gabarit échappe à tout : pas de déduplication, pas de dépendance, pas de version, pas de possibilité pour une extension d'optimisation de la traiter. Elle casse également les mécanismes de report et de combinaison proposés par les extensions de performance, qui ne voient que les ressources déclarées. Cette pratique se rencontre surtout dans les gabarits repris d'anciens projets, et sa correction est mécanique. Une recherche des balises de script dans le répertoire du thème donne en quelques secondes la liste des cas à traiter.

Le cas du thème enfant

Un thème enfant doit déclarer sa feuille de style en indiquant celle du parent comme dépendance, ce qui garantit que ses règles seront chargées après et prendront donc le dessus. Les méthodes anciennes, consistant à importer le parent depuis l'enfant, dégradent les performances en sérialisant les téléchargements. Ce point est simple et il est mal fait sur une proportion étonnante de thèmes enfants, ce qui produit des styles qui ne s'appliquent pas et des règles surchargées à coups de déclarations prioritaires. La correction tient en une ligne et supprime au passage une bonne partie des déclarations prioritaires accumulées.

Charger seulement ce qui sert

Le vrai levier de performance n'est pas la façon de déclarer mais la décision de charger ou non. C'est là que la plupart des sites perdent l'essentiel.

Le chargement conditionnel

Une ressource nécessaire à une seule page ne doit être déclarée que sur cette page, ce qui se fait en testant le contexte avant la déclaration. Une bibliothèque de carte chargée sur les huit cents pages d'un site alors qu'elle ne sert que sur la page de contact représente un gaspillage considérable. Ce test tient en une ligne et il est très rarement écrit, la déclaration inconditionnelle étant plus simple et le coût n'étant supporté par personne dans l'équipe. C'est pourtant l'intervention qui produit le gain le plus net sur la plupart des sites que nous reprenons.

Détecter la présence d'un composant

Lorsqu'une ressource sert à un composant inséré dans le contenu, la condition doit porter sur la présence effective de ce composant. Les versions récentes de WordPress permettent de déclarer une ressource depuis la fonction de rendu, même tardivement, ce qui résout élégamment la question. Sur les installations plus anciennes, une recherche du motif dans le contenu avant la génération de l'en-tête remplit le même office, comme nous l'évoquons dans notre article sur la manière de créer un shortcode moderne et sécurisé.

Retirer ce que l'on n'utilise pas

WordPress charge par défaut plusieurs ressources dont beaucoup de sites n'ont aucun usage : styles des blocs sur un site sans éditeur de blocs, feuille de style des émojis, scripts de commentaires sur un site sans commentaires. Chacune peut être retirée par une déclaration explicite. Le gain unitaire est modeste, l'accumulation ne l'est pas, et surtout ces retraits ne présentent aucun risque dès lors que la fonction correspondante n'est pas utilisée. Il faut simplement les documenter, un comportement absent surprenant toujours celui qui reprend le site.

Désactiver les ressources d'une extension

Une extension chargeant ses ressources partout alors qu'elle ne sert que sur quelques pages peut être neutralisée en retirant ses déclarations depuis le thème, à condition de le faire avec une priorité tardive. Cette intervention doit rester documentée, car elle produit un comportement surprenant pour quiconque reprendra le site sans le savoir. Elle vaut mieux qu'un remplacement de l'extension lorsque celle ci rend par ailleurs de bons services. Un commentaire indiquant pourquoi la déclaration est retirée suffit à rendre l'intervention compréhensible.

Différer et rendre asynchrone

Les attributs permettant de différer l'exécution d'un script ou de le rendre asynchrone se déclarent désormais directement dans les arguments de la déclaration, ce qui évite les filtres bricolés d'autrefois. Le report convient à la quasi totalité des scripts d'un site ordinaire, l'asynchrone étant réservé aux ressources indépendantes comme les outils de mesure. Ce réglage améliore sensiblement les indicateurs d'expérience pour un effort minime. Il faut en revanche vérifier que les scripts reportés ne dépendent pas d'un ordre d'exécution particulier avec des scripts non reportés.

Le cas des polices

Les polices web méritent un traitement particulier, leur chargement bloquant l'affichage du texte ou provoquant un changement de rendu perceptible. Elles se déclarent comme des feuilles de style, avec une préconnexion vers le domaine qui les héberge, et surtout avec un comportement d'affichage explicite. Ce dernier point est développé dans notre article sur la manière de maîtriser font-display et l'affichage des polices web.

Origine des ressources chargées sur une page d'accueil WordPress ordinaire
Extensions installées
47 %
Thème et thème enfant
26 %
Cœur de WordPress
14 %
Services tiers et mesure
9 %
Polices web
4 %

Répartition du poids des scripts et des styles chargés sur une page d'accueil. Près de la moitié provient d'extensions dont une partie n'a aucun usage sur cette page.

Diagnostiquer les conflits

Les problèmes de ressources produisent des symptômes déroutants, et une méthode simple permet de les identifier en quelques minutes plutôt qu'en une journée.

Lire l'ordre réel

Le code source de la page montre l'ordre effectif des balises produites, avec les numéros de version dans les adresses. Une lecture attentive révèle immédiatement les doublons, les versions divergentes et les ressources chargées avant leur dépendance. C'est le premier réflexe à avoir devant un comportement inexpliqué, et il donne la réponse dans la majorité des cas sans avoir à installer quoi que ce soit.

Repérer les doublons de bibliothèque

Deux versions d'une même bibliothèque déclarées sous des identifiants différents se chargent toutes les deux, la seconde écrasant la première en mémoire. Le symptôme est un comportement fonctionnant sur certaines pages et pas sur d'autres, selon l'ordre de chargement. La correction consiste à faire déclarer à chaque composant sa dépendance vers l'identifiant officiel plutôt qu'à embarquer sa propre copie, ce qui suppose parfois de contacter l'auteur d'une extension.

Isoler par désactivation

La méthode classique consiste à désactiver les extensions une par une jusqu'à identifier celle qui pose problème, puis à basculer sur un thème par défaut pour vérifier l'origine. Cette approche est fastidieuse et reste la plus fiable. Elle doit être menée sur une copie du site et non en production, précaution évidente qui n'est pas toujours prise dans l'urgence d'un incident.

Lire la console du navigateur

Les erreurs signalant qu'une fonction ou une variable n'existe pas indiquent presque toujours un problème d'ordre ou de dépendance manquante. Le nom de la fonction introuvable désigne directement la bibliothèque concernée. Cette lecture prend dix secondes et elle est régulièrement négligée au profit d'hypothèses, alors qu'elle donne souvent la réponse complète.

Se méfier des extensions d'optimisation

Les extensions qui combinent, minifient ou reportent les ressources modifient l'ordre et le contenu de ce qui est servi, ce qui produit des conflits absents sans elles. Devant un comportement incohérent, leur désactivation temporaire doit figurer parmi les premiers tests. Leur configuration comporte généralement une liste d'exclusions, qui est l'endroit approprié pour régler ces cas plutôt que de renoncer entièrement à l'optimisation.

Mesurer avant et après

Toute intervention sur le chargement doit être mesurée : nombre de requêtes, poids total, temps de blocage du fil principal. Ces trois valeurs se lisent dans les outils de développement du navigateur et donnent une réponse objective. Sans cette mesure, on empile des optimisations dont on ne sait pas si elles ont produit un effet, et l'on finit par en conserver certaines qui dégradent la situation sans que personne ne s'en aperçoive. La mesure se prend sur la même page et le même appareil avant et après chaque modification, condition sans laquelle les écarts observés relèvent davantage des conditions de mesure que du travail effectué.