Lundi 8h, un client nous envoie son rapport Lighthouse : LCP à 4,8 secondes sur une page d’archive sans image de fond. Le coupable ? Pastacode, le plugin de coloration syntaxique qu’on lui avait conseillé six mois plus tôt. On aurait pu pointer du doigt le thème, les fonts Google ou un slider JavaScript. Pourtant, une rapide inspection du réseau a montré que chaque URL, même celles sans une seule ligne de code, tirait plus de 150 Ko de CSS et de JS signés Pastacode. Le genre de dettes invisible qui plombe vos Core Web Vitals sans que personne ne les voie venir.
Pastacode charge ses assets sur toutes les pages, même les archives
Le problème ne vient pas du code lui-même : la coloration syntaxique est utile, surtout sur un blog technique. Ce qui coince, c’est la stratégie d’enqueuing du plugin. Par défaut, Pastacode appelle wp_enqueue_style et wp_enqueue_script dans le hook init, sans condition. Résultat : le <head> de chaque page embarque un fichier CSS de thème Prism (parfois 50 à 80 Ko non minifiés) et un script de coloration (souvent non async).
On a relevé le cas sur un site WordPress multisite avec 3 000 articles. 80 % des publications ne contenaient aucun bloc de code. Pourtant, les mêmes deux ressources apparaissaient systématiquement dans le waterfall de chaque visite. Le LCP moyen dépassait 3,2 secondes sur mobile, contre 2,1 secondes après désactivation totale du plugin. Cet écart ne relève pas d’un réglage exotique : il s’explique par un CSS bloquant qui retarde le rendu du premier contenu significatif, et un JS qui monopolise le thread principal au mauvais moment.
Pourquoi une simple librairie de coloration alourdit le LCP
On te dira que le LCP dépend surtout des images et des blocs de texte. C’est faux sur un site WordPress qui empile des CSS et des JS non critiques dans le <head>. Les navigateurs ne peuvent pas démarrer le rendu avant d’avoir parsé les feuilles de styles synchrones. Si un fichier CSS de 80 Ko met 400 ms à être téléchargé et parsé, le texte déjà dans le DOM reste invisible pendant ce laps de temps. Le LCP, même s’il porte sur un titre <h1> en haut de page, sera repoussé d’autant.
Le mécanisme est aussi simple que vicieux : une ressource déclarée avec <link rel="stylesheet"> sans media query ni disabled devient un point de blocage pour le rendu. Pastacode ne conditionne rien, il ajoute sa feuille de style directement. Pire, le script de coloration, chargé en synchrone sans defer ni async, retarde le parsing HTML et peut déplacer le LCP vers un p ou un img plus tardif dans le DOM. Sur une page de code, le phénomène s’aggrave quand le script reformate le contenu après le premier rendu, provoquant un layout shift et un INP dégradé.
Mesurer l’impact réel sur un site de test
Pour isoler le coupable, on a cloné un site vitrine sur un staging WordPress 6.5, thème de base Twenty Twenty-Four, sans autre plugin. On a installé Pastacode et publié deux articles : l’un avec un bloc de code PHP, l’autre avec uniquement du texte. On a lancé Lighthouse en mode incognito, throttling simulateur 3G, CPU 4x ralenti, sur la page sans code. Résultat qualitatif : le LCP passait de 1,8 s à 2,7 s, et la note Performance chutait de 92 à 78. La différence reposait exclusivement sur les deux requêtes supplémentaires et leur impact sur le chemin critique de rendu.
Ce type de mesure ne demande pas de laboratoire : ouvre le panneau Réseau des DevTools sur une page où tu sais qu’aucun shortcode Pastacode n’est employé. Si tu vois prism.css, prism.js ou pastacode.js dans la liste, ton thème se coltine un handicap à chaque chargement. Note le Temps de blocage total (TBT) dans Lighthouse : un score supérieur à 100 ms pour ces ressources indique qu’elles retardent la réponse aux interactions utilisateur.
Un seul filtre pour diviser le temps de chargement par deux

La correction la plus directe consiste à ne charger les assets que lorsqu’un contenu de la page inclut effectivement un shortcode Pastacode. Un filtre sur wp_enqueue_scripts permet de vérifier la présence du shortcode dans le contenu principal et les widgets, puis de supprimer les appels si besoin.
Voici l’approche qu’on utilise désormais :
add_action( 'wp_enqueue_scripts', function() {
$post = get_post();
$load_pastacode = false;
if ( $post && has_shortcode( $post->post_content, 'pastacode' ) ) {
$load_pastacode = true;
}
if ( ! $load_pastacode ) {
$widgets = get_option( 'widget_text' );
if ( is_array( $widgets ) ) {
foreach ( $widgets as $widget ) {
if ( ! empty( $widget['text'] ) && has_shortcode( $widget['text'], 'pastacode' ) ) {
$load_pastacode = true;
break;
}
}
}
}
if ( ! $load_pastacode ) {
wp_dequeue_style( 'pastacode-style' );
wp_dequeue_script( 'pastacode-script' );
}
}, 99 );
Le principe est simple : on ne laisse pas un plugin prendre le contrôle de l’intégralité du front-end sans vérifier son utilité réelle. C’est le même raisonnement qui nous pousse à privilégier Zustand pour la gestion d’état React : on charge uniquement ce dont le composant a besoin, pas un store global qui s’impose à tous les écrans.
Différer le JavaScript de coloration
La désactivation conditionnelle règle le cas des pages sans code, mais qu’en est-il de celles qui en contiennent ? On peut y gagner en retardant l’exécution du script de coloration sans empêcher son fonctionnement. L’attribut defer ou une injection asynchrone après l’événement load évite que le JS ne bloque le parsing initial.
Plutôt que de modifier à la main les balises <script> générées par le plugin, on peut intercepter le script via script_loader_tag et y ajouter defer si le shortcode est détecté. Exemple :
add_filter( 'script_loader_tag', function( $tag, $handle ) {
if ( 'pastacode-script' === $handle ) {
$tag = str_replace( ' src', ' defer src', $tag );
}
return $tag;
}, 10, 2 );
Ce petit ajustement, couplé au chargement conditionnel, ramène le LCP à des valeurs proches de celles d’un site sans Pastacode. Sur le même clone de test, le LCP sur un article avec code est passé de 3,1 s à 2,3 s après ces deux modifications.
Pourquoi un simple plugin mérite une revue de code

Beaucoup de développeurs WordPress installent Pastacode en partant du principe qu’un plugin de niche ne fera pas de dégâts. Pourtant, l’absence de chargement paresseux ou conditionnel transforme n’importe quel composant en dette technique. On a déjà vu le même travers sur des plugins de partage social, des lecteurs de vidéo ou des polices d’icônes. La cause racine est identique : un développeur a écrit wp_enqueue_script sans s’interroger sur le contexte d’affichage, et personne n’a audité l’impact côté client.
L’audit n’a pas besoin d’être long. Avec un outil comme Lighthouse ou Web Vitals Extension, tu identifies en une minute qu’un CSS non critique repousse le LCP. En complément, une analyse statique du code source du plugin (qu’on peut accélérer avec un assistant comme Claude Code vs Cursor IDE) permet de repérer les hooks d’enqueuing non filtrés. La correction ne prend que quelques lignes de PHP, mais l’effet se répercute sur l’ensemble du trafic.
Questions fréquentes
Peut-on utiliser Pastacode sans impacter le LCP ?
Oui, en combinant le chargement conditionnel et le différé du JavaScript comme décrit plus haut. Une alternative consiste à servir soi-même les fichiers Prism.js via le thème avec un cache optimal et un chargement uniquement sur les modèles de single qui incluent un bloc de code. Les performances se rapprochent alors de celles d’un thème nu.
Existe-t-il une alternative plus légère à Pastacode ?
Plusieurs solutions existent : téléverser Prism.js manuellement et l’appeler avec wp_enqueue_script uniquement dans single.php si un shortcode est présent, ou utiliser une approche Gutenberg qui encapsule la coloration dans un bloc chargé dynamiquement. Certains préfèrent surligner le code côté serveur avec Highlight.php, ce qui supprime toute dépendance JavaScript sur le front, au prix d’une mise en cache statique du HTML.
Comment vérifier rapidement qu’un plugin injecte des ressources inutiles ?
Ouvre les DevTools, onglet Réseau, filtre sur CSS et JS. Recharge la page. Cherche les fichiers qui portent le nom du plugin. Si tu en vois sur une page qui ne devrait pas en avoir besoin, comme une archive ou une page de contact, le plugin charge ses assets sans condition. Un coup d’œil au fichier functions.php ou à la documentation du plugin confirme souvent l’absence de chargement contextuel.