vendredi 25 septembre 2026

À propos

Contact

Blocs Gutenberg

Alléger le JavaScript d’un bloc : dépendances externalisées et code splitting

Un bloc dont le bundle pèse 300 Ko plombe le chargement de la page. Recette pour vérifier les dépendances externalisées, importer dynamiquement et couper le superflu.

Par Clément Hadrot • 11 février 2025 • 5 min de lecture • Aucun commentaire
Alléger le JavaScript d'un bloc : dépendances externalisées et code splitting

Un bloc de sélection de couleur avancée (une sorte de nuancier personnalisé pour un configurateur de produit) affichait un temps de chargement anormalement long sur les pages qui l’utilisaient. En creusant, le bundle JavaScript front pesait 340 Ko non compressés, pour un composant qui, visuellement, ne semblait pas justifier un tel poids. Voici la démarche suivie pour identifier et corriger le problème, étape par étape, sans optimisation à l’aveugle.

Le point de départ : ne jamais optimiser avant d’avoir mesuré précisément ce qui compose réellement le bundle. Une intuition sur la cause d’un bundle lourd se trompe étonnamment souvent.

Analyser le bundle avant d’agir

@wordpress/scripts intègre déjà webpack-bundle-analyzer en configuration de base ; il suffit de définir la variable d’environnement adéquate pour générer un rapport visuel après un build.

WP_BUNDLE_ANALYZER=true npx wp-scripts build

Sur ce projet, le rapport a révélé que 210 Ko des 340 Ko provenaient d’une bibliothèque de conversion de couleurs (RGB, HSL, LAB, CMYK) importée en intégralité alors que seules deux fonctions de conversion RGB↔HSL étaient réellement utilisées dans le code du bloc.

Vérifier les dépendances déjà externalisées

Avant de chercher des solutions compliquées, un réflexe trop souvent oublié : vérifier que le code n’importe pas par erreur une copie complète d’un paquet @wordpress/* que WordPress fournit déjà globalement. @wordpress/scripts externalise automatiquement les paquets officiels listés dans @wordpress/dependency-extraction-webpack-plugin (React, les composants, les data stores…), à condition qu’ils soient importés de façon standard depuis leur paquet npm officiel plutôt que via un chemin relatif copié dans le dépôt.

// Correct : externalisé automatiquement, aucun poids ajouté au bundle du bloc
import { useState } from '@wordpress/element';

// Incorrect : une copie locale de React, dupliquée dans le bundle
import { useState } from '../../vendor/react/index.js';

Sur ce projet précis, ce point était déjà correct — le poids venait bien d’une dépendance tierce légitimement empaquetée, pas d’une externalisation manquée.

L'essentiel à retenir : Vérifier d'abord ce que @wordpress/scripts externalise déjà automatiquement ; Importer dynamiquement les parties du bloc utilisées rarement ; Analyser le bundle avant d'optimiser à l'aveugle

Importer dynamiquement les parties peu utilisées

Le nuancier proposait un mode avancé, rarement activé (moins de 5 % des sessions selon les statistiques d’usage du client), qui embarquait un sélecteur de couleur complet avec conversion vers tous les espaces colorimétriques cités plus haut. Plutôt que de charger ce code pour 100 % des visiteurs, on l’a extrait dans un import() dynamique déclenché uniquement à l’ouverture du mode avancé.

async function ouvrirModeAvance() {
    const { initialiserSelecteurAvance } = await import(
        /* webpackChunkName: "mode-avance-couleur" */ './mode-avance.js'
    );
    initialiserSelecteurAvance( conteneurRef.current );
}

Ce simple changement isole le code du mode avancé dans un fichier séparé, chargé à la demande seulement, ramenant le poids du chargement initial de 340 Ko à 95 Ko pour l’immense majorité des visiteurs qui n’ouvrent jamais ce mode.

Remplacer une dépendance surdimensionnée

Pour la conversion RGB↔HSL réellement utilisée dans le mode standard, la bibliothèque complète (avec support de CMYK, LAB, et une dizaine d’autres espaces colorimétriques jamais utilisés) a été remplacée par deux fonctions écrites à la main, chacune de moins de vingt lignes — une conversion RGB vers HSL n’est pas un algorithme complexe, et cette portion ne justifiait clairement pas une dépendance de plusieurs dizaines de kilo-octets.

function rgbVersHsl( r, g, b ) {
    r /= 255; g /= 255; b /= 255;
    const max = Math.max( r, g, b );
    const min = Math.min( r, g, b );
    let h, s;
    const l = ( max + min ) / 2;

    if ( max === min ) {
        h = s = 0;
    } else {
        const d = max - min;
        s = l > 0.5 ? d / ( 2 - max - min ) : d / ( max + min );
        switch ( max ) {
            case r: h = ( g - b ) / d + ( g < b ? 6 : 0 ); break;
            case g: h = ( b - r ) / d + 2; break;
            case b: h = ( r - g ) / d + 4; break;
        }
        h /= 6;
    }
    return { h: h * 360, s: s * 100, l: l * 100 };
}

Résultat final et arbitrages

  • Bundle front initial ramené de 340 Ko à 68 Ko non compressés, soit une division par cinq.
  • Le mode avancé, désormais chargé à la demande, ajoute environ 90 Ko supplémentaires uniquement pour les visiteurs qui l’ouvrent réellement.
  • Écrire deux fonctions de conversion à la main plutôt que de dépendre d’une bibliothèque tierce a un coût de maintenance à surveiller : si un futur besoin nécessite d’autres espaces colorimétriques, il faudra réévaluer ce choix.

Sur ce projet, le réflexe qui a le plus servi n’était pas une technique précise, mais la discipline de mesurer avant d’agir : sans le rapport de webpack-bundle-analyzer, l’équipe aurait probablement cherché à optimiser le code du bloc lui-même, alors que le vrai poids venait d’une dépendance tierce largement sous-utilisée.

En résumé

Alléger le JavaScript d’un bloc suit toujours la même méthode : mesurer avec un analyseur de bundle avant d’agir, vérifier que les paquets @wordpress/* sont bien externalisés, isoler en chargement différé ce qui n’est utilisé que par une minorité de visiteurs, et, en dernier recours, remplacer une dépendance surdimensionnée par du code ciblé quand la fonctionnalité réellement utilisée est simple. Sur ce nuancier, ces quatre leviers combinés ont divisé par cinq le poids initial du bundle.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi