Mardi 14h, un client nous envoie sa Search Console. 4 800 URLs en allemand venaient de passer en « Page non indexée ». Aucun changement de code, aucune migration. Juste la mise à jour automatique de son plugin de traduction WordPress. Trois jours plus tôt, tout était normal. Le temps de dérouler les logs, on a retrouvé le souci : les balises hreflang avaient disparu du DOM, remplacées par des liens canoniques pointant tous vers la version française. Résultat, Google a considéré que chaque page en allemand n’était qu’une copie et les a virées de l’index.
On a perdu deux jours à corriger le tir. Deux jours pendant lesquels les ventes sur les marchés DACH ont plongé. La morale n’est pas qu’il faut fuir les plugins de traduction, mais que si vous en installez un sans mesurer son impact sur le rendu, l’indexation et le crawl, vous jouez à la roulette russe avec vos Core Web Vitals.
Le vrai problème n’est pas la traduction, c’est le rendu
L’immense majorité des plugins multilingues pour WordPress ajoutent une couche de traitement au moment du rendu de la page. Soit ils interceptent les chaînes côté serveur à l’aide de filtres PHP, soit ils réécrivent le DOM en JavaScript une fois la page livrée.
Dans les deux cas, ça a un coût. Le premier augmente le Time to First Byte. Le second retarde le Largest Contentful Paint parce qu’une partie du texte n’apparaît qu’après exécution d’un script qui analyse les balises et remplace les libellés. Ce script, souvent chargé en render-blocking, s’exécute avant que le navigateur ait fini de peindre le titre principal. Si votre LCP est ce titre, vous venez de lui coller un retard de 400 à 800 ms sur mobile.
On a mesuré le phénomène sur une boutique WooCommerce avec un trafic à 60 % mobile. La version française affichait le LCP en 2,1 s. La version anglaise, générée par la surcouche JavaScript d’un plugin connu, plafonnait à 3,6 s sur le même serveur, la même base. La seule variable, c’était le DOM rewriting. Même les polices et les images optimisées ne rattrapaient pas ce temps perdu.
La solution ne se trouve pas dans les réglages du plugin. Elle se trouve dans ce que vous faites en amont, avant même d’activer la traduction. Si votre site est déjà à la limite des seuils de Core Web Vitals, cette surcouche suffit à vous faire basculer en rouge.
Pourquoi les hreflang auto-générées ne sont jamais fiables à 100 %
Les algorithmes des plugins de traduction créent des balises hreflang et canoniques en se basant sur la structure de vos permaliens et la configuration de votre multisite ou de vos sous-répertoires. C’est propre, tant que personne ne touche à un paramètre. Sauf qu’en réalité, on touche toujours à un paramètre.
Un thème qui ajoute un filtre wp_head(), une extension SEO qui reformate les URLs, un CDN qui réécrit les réponses : un seul de ces mouvements et les hreflang se mettent à pointer vers la mauvaise langue, se dupliquent ou disparaissent. Google réagit vite. Dès qu’il ne trouve plus de signal de variation linguistique, il applique son propre clustering. Dans le meilleur des cas, il choisit une seule version à indexer. Dans le pire, il exclut les deux pour contenu dupliqué.
Quand on audite ce genre de site, on commence toujours par un curl -I sur chaque version de langue. On vérifie les en-têtes Link et on extrait le source HTML complet. Le nombre de fois où on y découvre une balise canonique autocentrée sur la langue principale au lieu de la langue secondaire est sidérant.
Ce qui est contre-intuitif, c’est que Google peut tout de même classer vos pages traduites, même avec des hreflang défaillantes, si le contenu est suffisamment singulier. Mais la probabilité de cannibalisation explose. Le jour où vous perdez du trafic, vous ne savez pas que c’est à cause de cette incohérence qui dort dans votre DOM depuis six mois.
Mesurez AVANT d’activer le plugin multilingue
La plupart des équipes développent leur site en monolingue, valident leurs scores Core Web Vitals en fin de projet, puis activent le plugin de traduction une semaine avant la mise en ligne. C’est une erreur d’architecture.
Si vous voulez savoir ce que le plugin ajoute réellement, clonez votre environnement dans un staging strictement identique, activez le plugin, générez une version traduite d’une page clé, et passez-la dans Lighthouse ou PageSpeed Insights. Comparez le filmstrip, le tracé de l’activité réseau, et le rapport de l’onglet Performance.
Observez deux choses :
- Le nombre de requêtes JavaScript supplémentaires que le plugin injecte. Certains chargent leurs propres bundles, des JSON de traduction, parfois même un iframe pour un outil d’édition front-end. Chaque requête supplémentaire allonge le chargement.
- L’ordre dans lequel le texte traduit apparaît à l’écran. Si le contenu principal clignote ou n’apparaît qu’après une seconde visible de blanc, votre LCP est dans le rouge. Le navigateur a déjà peint le gros bloc, puis le script est venu changer sa couleur ou son texte, forçant une nouvelle peinture.
L’idéal est de réaliser ce test sur une connexion LTE limitée et un mobile milieu de gamme. C’est le terrain réel de votre audience. Un déploiement côté serveur vous paraîtra peut-être fluide sur une fibre optique ; il ne le sera pas sur un réseau 4G instable.
Ce que le serveur peut faire pour limiter les dégâts
Vous pouvez conserver votre plugin de traduction et lui redonner de l’air en agissant sur la couche d’hébergement et de cache.
D’abord, le cache de page est votre meilleur allié. Si vos pages traduites sont servies en cache complet (HTML statique), le traitement PHP de traduction ne se déclenche qu’au moment de la régénération du cache, pas à chaque visite utilisateur. En pratique, un must-revalidate mal calé sur la version traduite ruine ce bénéfice. Vérifiez les en-têtes cache-control de vos pages dans chaque langue.
Ensuite, placez le script de rewriting DOM en chargement différé via fetchpriority="low" si le plugin vous le permet. Si le plugin injecte de manière rigide du JavaScript sans filtre, vous pouvez le bloquer dans la file d’attente du navigateur avec un simple snippet dans functions.php qui le passe en script avec l’attribut defer. C’est brutal, mais tant que le contenu principal s’affiche avant l’intervention de traduction, le LCP est sauf.
Enfin, pour les sites à fort trafic, une règle edge sur un CDN capable de router les requêtes par langue peut servir directement la bonne version sans même toucher au serveur d’origine. Cette approche désamorce complètement l’overhead du plugin. Elle transforme ce qui était un goulot d’étranglement PHP en une ressource statique servie à la volée.
Et si on sortait la traduction du rendu WordPress ?
La vraie cassure se produit quand on accepte que WordPress ne soit plus responsable de la traduction dynamique, mais seulement un dépôt de contenus multilingues déjà compilés.
L’approche headless le démontre bien. Un front-end React, Next.js ou Remix consomme les données via l’API REST ou GraphQL. La couche de traduction, elle, est gérée au moment du build ou dans le state management côté client. On a expérimenté cette architecture avec Zustand couplé à un dictionnaire JSON chargé paresseusement : le temps d’hydratation chute et le LCP devient le même quelle que soit la langue, puisque le texte est déjà dans le HTML livré par le serveur de rendu.
Ce n’est pas une solution pour tout le monde. Elle demande une refonte front-end, un découplage et une maturité technique qu’une petite équipe n’a pas toujours. Mais si vous en êtes au stade où la performance est un critère de vente et que vous maintenez un site e-commerce en six langues, le calcul change. Abandonner le plugin de traduction pour une architecture de build statique multilingue fait parfois gagner plus en taux de conversion que tout le travail d’optimisation incrémentale précédent.
Et si vous codez cette migration, sachez qu’un assistant comme Claude Code peut générer la structure de base du state multilingue et injecter les fichiers de traduction à la compilation. On a testé sur un side-project de boutique en italien et en français : le site est passé d’un LCP de 4,2 s sous WPML à 1,7 s en React avec des pages pré-générées.
Quand un plugin reste le choix pragmatique
Tout le monde n’a pas un budget de refonte. Si votre CMS est verrouillé, que vos rédacteurs ont besoin d’un éditeur visuel et que le délai est de deux semaines, vous prenez un plugin. Mais vous le choisissez sur un critère que personne ne met en avant : la transparence de son pipeline de rendu. Vous voulez voir, avant de l’installer, comment il gère les requêtes HTTP, quels scripts il charge, et s’il propose un mode de cache statique. Si la documentation du plugin est muette sur ces points, passez votre chemin.
Questions fréquentes
Un plugin de traduction gratuit est-il forcément plus lent qu’un premium ?
Pas mécaniquement. Certains gratuits font du simple remplacement de chaînes sans surcharge JavaScript et restent plus légers que des suites premium alourdies par des éditeurs visuels ou des intégrations externes. C’est le profil de chargement qu’il faut auditer.
Les plugins de traduction impactent-ils le SEO local au-delà des hreflang ?
Oui. Si le plugin génère des URLs identiques pour des contenus traduits juste par un paramètre, Google peut avoir du mal à séparer les versions régionales. Une configuration propre de sous-répertoires ou de sous-domaines par langue reste la seule manière fiable de viser un marché local.
Peut-on garder un plugin de traduction et passer au Core Web Vitals « bon » sur mobile ?
C’est possible à condition de placer le cache en frontal et de désactiver toute transformation JavaScript du contenu principal. Dès que le texte visible dépend d’un script, l’objectif mobile devient très difficile à tenir.