Optimiser WordPress : Pnwy sous Stéroide !

La licorne Geekeries allège une page WordPress en retirant une police et des fichiers inutiles

Salut à tous, j’ai profité d’une maintenance récente pour enfin (ré)optimiser le WordPress de Geekeries.org. Pas en installant un énième plugin miracle, mais en regardant ce que le navigateur chargeait vraiment.

Le site n’était pas à genoux. Il fonctionnait, les pages s’ouvraient, et personne ne m’avait signalé de catastrophe. PageSpeed lui me scorait pourtant à 72 sur mobile et 73 sur ordinateur. Le plus visible était le décalage de mise en page : le logo arrivait sans dimensions réservées et poussait le contenu pendant le chargement.

J’ai donc repris la chaîne complète, du reverse proxy jusqu’au navigateur, avec deux règles assez simples : une modification à la fois, et un retour arrière prêt avant de toucher à la production. Pwny m’a aidé à faire l’inventaire et à préparer les contrôles, et les appliquer mais chacun autorisé et vérifié manuellement.

Le serveur n’était pas le principal coupable

Une requête sur le site suit ce chemin : visiteur → Nginx Proxy Manager → Nginx et PHP → WordPress → MariaDB et Redis. Mon premier réflexe aurait pu être de régler PHP-FPM ou d’ajouter encore du cache. Les mesures racontaient autre chose.

Une fois la page anonyme servie à chaud, le TTFB tournait autour de 17 à 23 ms. Le temps de blocage JavaScript était déjà à zéro. En revanche, le navigateur recevait encore des feuilles de style bloquantes, une police entière pour quatre icônes, des images pas toujours à la bonne taille et un logo qui déclenchait du CLS.

Autrement dit : ce n’était pas le moment de serrer les vis de PHP-FPM. J’ai laissé cette partie tranquille et je me suis concentré sur la livraison de la page. J’ai tout de même corrigé une incohérence côté cache. W3 Total Cache utilisait déjà Redis, mais son cache des page HTTPS n’était pas actif… Je l’ai donc activé uniquement pour les visiteurs anonymes (c’est à dire tout le monde sauf moi ici).

Nginx Proxy Manager avait aussi son option « Cache Assets » active. Je l’ai désactivée : les fichiers statiques reçoivent déjà leurs en-têtes de cache d’un an depuis l’origine. Deux couches qui prétendent gérer le même cache ne rendent pas forcément un site deux fois plus rapide. Elles rendent surtout le diagnostic plus pénible !

Commencer par ce qui bougeait vraiment

Le premier correctif visible a tenu en peu de lignes. Le logo connaît maintenant sa taille réelle, 462 × 115 pixels, et il n’est plus chargé « paresseusement » (lol, coucou l’Agence, on lit « lazy » chez les gens normaux). Le navigateur peut donc réserver sa place dès la lecture du HTML.

Le CLS est passé de 0,291 à 0 sur mobile et de 0,397 à 0 sur ordinateur. C’est le changement que je préfère dans cette passe : il ne cherche pas à flatter un score, il empêche réellement la page de sauter sous le doigt.

Pour les images, j’ai utilisé ce que WordPress sait déjà faire. Le plugin Modern Image Formats génère les versions WebP tout en gardant le format d’origine en secours, et WordPress fournit le srcset. L’image principale de la page d’accueil, celle de mon article sur la mise à jour de MariaDB avec Docker et Watchtower, ont donc reçu ses variantes adaptées.

Je n’ai pas régénéré toute la médiathèque pour le plaisir. Les tailles 450, 600 et 640 pixels existaient déjà, et ajouter mécaniquement une variante de 384 pixels n’aurait pas garanti son utilisation sur un écran mobile à forte densité. J’ai régénéré les quelques images qui comptait, contrôlé le HTML produit, puis vérifié dans le HAR le fichier réellement téléchargé.

Alléger le thème, mais pas à la tronçonneuse

Mon thème Responsive Mobile traînait encore Bootstrap, jQuery Core, jQuery Migrate, Font Awesome et quelques petits fichiers de confort. J’ai commencé par différer les scripts qui pouvaient l’être. Ensuite, j’ai cherché si les composants Bootstrap étaient réellement présents dans les pages publiées.

Ils ne l’étaient pas sur les routes actives. Bootstrap CSS et JavaScript ont donc pu être retirés de ces pages ! Tout en gardant une exception pour l’ancien contenu qui pourrait encore en avoir besoin. Même traitement pour quelques ressources secondaires : elles ont été retardées ou supprimées seulement après avoir vérifié le menu mobile, les commentaires, le bouton de retour en haut et la bannière d’information.

Pour que tout cela survive à une mise à jour, j’ai ressorti un thème enfant Responsive II qui existait déjà (créé il y a des années déjà à des fins d’optimisation). Les surcharges sont maintenant dans le thème enfant et le thème parent reste intact. Ce n’est pas très spectaculaire dans PageSpeed, mais c’est ce qui évitera de refaire le travail dans six mois.

Il y a aussi eu une tentative moins heureuse : les anciens groupes de minification W3TC ont fini par dupliquer des ressources au lieu de les alléger… bien joué W3TC… Je les ai retirés et je suis revenu aux fichiers minifiés du thème. C’était plus simple, plus lisible, et surtout mesurable.

La police qui refusait de partir

Font Awesome méritait sa propre petite enquête. Le site n’utilisait que quatre icônes : le menu mobile et trois liens sociaux. Charger une police WOFF de plus de 70 Ko pour cela n’avait plus beaucoup de sens. J’ai donc remplacé ces quatre icônes par des masques SVG dans le thème enfant. Visuellement, tout était bon. Le CSS était bon. Et pourtant, le test suivant téléchargeait toujours la police.

La raison était cachée dans le style calculé des pseudo-éléments. Le thème parent leur appliquait encore font-family: FontAwesome, même si leur contenu avait été remplacé par un masque SVG. Chrome voyait donc toujours une raison de résoudre la police. Champion !

Le correctif final tenait en une ligne, ajoutée sur les quatre sélecteurs concernés : font-family: inherit;. Le test réseau suivant ne contenait plus aucune requête de police. Gain net : une requête et 72 438 octets sur mobile comme sur ordinateur.

C’est un bon rappel. Voir la bonne icône à l’écran ne prouve pas que l’ancienne ressource a disparu. Pour ce genre de changement, il faut regarder le réseau, pas seulement la page.

Optimiser WordPress, sans vendre du rêve

Après la dernière correction, PageSpeed affiche 93 sur mobile et 100 sur ordinateur. Le CLS est à zéro sur les deux profils, le TBT reste à zéro, le FCP est mesuré à 1,86 s sur mobile et 0,52 s sur ordinateur. Le LCP termine à 2,62 s sur mobile et 0,60 s sur ordinateur.

Le Speed Index mobile est passé de 7,5 s à 4,38 s. Sur ordinateur, il est passé de 2,8 s à 0,53 s. C’est nettement mieux, mais je ne vais pas prétendre que chaque dixième vient d’une seule ligne de CSS. PageSpeed reste un test de laboratoire, sensible aux conditions de la mesure. Mais on sait que la performance d’un site impact le SEO (et donc votre traffic), cela vaut donc le coup d’améliorer ses perfs (et puis le serveur peut absorber plus de charge, double bonus) !

Le LCP mobile, en particulier, n’a pas miraculeusement fondu. Aller chercher les derniers dixièmes demanderait probablement plus de CSS critique, plus de variantes par appareil ou une logique de chargement plus complexe. Pour le moment, le rapport gain, risque et maintenance n’est pas assez bon.

Je vais donc laisser le site vivre et attendre assez de trafic pour regarder les vraies données Core Web Vitals. Un score de 100 en laboratoire est sympa mais une page stable, légère et facile à maintenir m’intéresse davantage.

Sur un WordPress qui a vécu, le meilleur point de départ n’est pas la liste automatique de Lighthouse. C’est la différence entre ce que le serveur fait, ce que WordPress génère et ce que le navigateur télécharge réellement.

Le reste tient dans une méthode que je garderai pour optimiser WordPress : Faire un tour sur https://pagespeed.web.dev/, passer le resultat à Pnwy (Codex) et le laisser faire, il va : sauvegarder la conf en cours, changer le point à améliorer, tester en visiteur, vérifier le HAR, puis conserver ou annuler le change. Ce n’est pas une recette magique. C’est juste un bon geek 🙂 !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. Découvrez comment les données de vos commentaires sont traitées.