Skip to content

Tout pour WordPress, le développement web — et plus encore

⚡ Contact Form 7 - chargement différé des scripts et styles pour accélérer WordPress

⚡ Contact Form 7 - chargement différé des scripts et styles pour accélérer WordPress

Comment CF7 ralentit votre site et pourquoi vous pouvez le corriger en 5 minutes

Contact Form 7 est installé sur plus de 5 millions de sites WordPress. Le plugin est fiable, flexible et gratuit, et les formulaires de contact créés avec lui fonctionnent sur pratiquement tous les sites. Mais cette commodité a un revers: par défaut, CF7 charge son CSS et son JavaScript sur chaque page de votre site, même quand aucun formulaire ne s'y trouve.

Pour la page d'accueil, le blog, les pages d'atterrissage et des dizaines d'autres pages, c'est du poids mort: requêtes supplémentaires, augmentation du DOM Content Loaded, taille de page gonflée. En chiffres, environ 10 à 30 Ko de trafic compressé et 1 à 2 requêtes bloquantes sans raison. PageSpeed Insights ne pardonne pas ce genre de choses.

Cela peut se corriger de trois manières, d'un simple defer en deux lignes à un chargement conditionnel soigné «dans les règles de l'art» selon le développeur du plugin. Nous allons détailler chaque méthode, avec le code et sans superflu.

💡 Aperçu rapide:

  • Désactiver le chargement global de CF7 via les constantes WPCF7_LOAD_JS et WPCF7_LOAD_CSS dans wp-config.php, la méthode officielle la plus propre.
  • Réactiver les scripts et les styles, mais uniquement sur les pages contenant un formulaire, via wpcf7_enqueue_scripts() dans le template de page.
  • Pour les bundles personnalisés, le package lazy-cf7-assets, qui détecte automatiquement le formulaire sur la page et charge le JS de manière dynamique.

Méthode 1: différer le chargement du script CF7 via functions.php

L'option la plus rapide et la plus simple consiste à ajouter l'attribut defer au script de Contact Form 7. Il indique au navigateur: «charge le fichier en arrière-plan, mais exécute-le quand le DOM est prêt». Le formulaire continue de fonctionner, mais le script ne bloque plus le rendu de la page.

Ajoutez ce code à functions.php dans votre thème actif (ou via le plugin Code Snippets, plus sûr lors des mises à jour):

1if ( ! function_exists( 'add_defer_to_cf7' ) ) {
2 function add_defer_to_cf7( $url ) {
3 if (
4 false === strpos( $url, 'contact-form-7' ) ||
5 false === strpos( $url, '.js' )
6 ) {
7 return $url;
8 }
9 return "$url' defer='defer";
10 }
11 add_filter( 'clean_url', 'add_defer_to_cf7', 11, 1 );
12}

La fonction vérifie l'URL de chaque script mis en file d'attente via le hook clean_url. Si l'adresse contient contact-form-7 et l'extension .js, elle ajoute defer='defer'. Tous les autres scripts ne sont pas modifiés.

Avantage: une solution en 10 lignes qui ne nécessite pas de modifier les templates ou la configuration du plugin. Convient aux thèmes où il n'existe pas de template de page de contact séparé.

Inconvénient: le script se charge toujours sur chaque page, vous supprimez seulement le comportement bloquant pour le rendu. Le trafic et les requêtes serveur ne sont pas réduits. Cette méthode n'affecte pas du tout le CSS du plugin, la feuille de style se charge comme d'habitude.

Méthode 2: méthode officielle, chargement conditionnel via des constantes

Cette approche est décrite dans la documentation de Contact Form 7 par le développeur du plugin lui-même, Takayuki Miyoshi. L'idée comporte deux étapes: d'abord désactiver globalement les scripts et styles de CF7, puis les réactiver, mais uniquement sur les pages où le formulaire est effectivement utilisé.

Étape 1: désactiver le chargement sur toutes les pages

Ajoutez deux constantes à wp-config.php:

1define( 'WPCF7_LOAD_JS', false );
2define( 'WPCF7_LOAD_CSS', false );

Alternativement, via le functions.php de votre thème:

1add_filter( 'wpcf7_load_js', '__return_false' );
2add_filter( 'wpcf7_load_css', '__return_false' );

Après cela, CF7 ne chargera plus une seule ligne de son code sur aucune page de votre site, y compris celles où un formulaire existe. Sans scripts, le formulaire perd la soumission AJAX et la validation, d'où la nécessité de l'étape 2.

Étape 2: restaurer les scripts sur les pages contenant un formulaire

Supposons que votre page de contact utilise le template page-contact.php dans le dossier de votre thème. Ajoutez ceci à ce template avant l'appel à wp_head():

1if ( function_exists( 'wpcf7_enqueue_scripts' ) ) {
2 wpcf7_enqueue_scripts();
3}
4
5if ( function_exists( 'wpcf7_enqueue_styles' ) ) {
6 wpcf7_enqueue_styles();
7}

Les fonctions wpcf7_enqueue_scripts() et wpcf7_enqueue_styles() chargent manuellement les scripts et styles de CF7 uniquement sur ce template. Toutes les autres pages de votre site restent propres.

Avantage: la méthode est «du constructeur», garantie de ne pas casser lors des mises à jour du plugin. Compatible avec les versions 5.x et 6.x de CF7, version actuelle 6.1.6 en juin 2026 (liste des versions). Aucun chargement inutile sur les pages sans formulaire.

Inconvénient: nécessite de modifier les templates du thème. Si vous avez plusieurs pages avec des formulaires, vous devez penser à ajouter les appels dans chaque template. Si le formulaire est inséré via un shortcode dans le contenu (plutôt que dans un template), la méthode ne fonctionnera pas sans conditions supplémentaires.

Méthode 3: le package lazy-cf7-assets pour les bundles JavaScript

Si vous construisez votre frontend avec un bundler (Webpack, Vite, esbuild) et utilisez un thème moderne avec un bundle JavaScript personnalisé, il existe un package npm appelé lazy-cf7-assets. Il résout le même problème, mais côté client: il scanne le DOM, trouve le formulaire CF7 et charge ensuite dynamiquement les scripts du plugin.

Installation:

1npm install lazy-cf7-assets

Avant de l'utiliser, vous devez désactiver le chargement automatique du JS par le plugin (comme dans la méthode 2, via wpcf7_load_js):

1add_filter( 'wpcf7_load_js', '__return_false' );

Ensuite dans votre bundle JS:

1import lazyform from 'lazy-cf7-assets';
2
3// Initialize after DOM ready
4lazyform.init();

Si les scripts se chargent dans le <head> plutôt qu'à la fin du <body>, spécifiez un chemin absolu vers l'image GIF de chargement pour que le formulaire ne «scintille» pas dans un état vide:

1lazyform.init({
2 gifPath: '/wp-content/themes/my-theme/images/ajax-loader.gif'
3});
Capture d'écran du dépôt lazy-cf7-assets sur GitHub

Avantage: aucune intervention côté PHP, pas besoin de modifier les templates pour chaque page avec un formulaire. Le package détecte automatiquement si un shortcode CF7 existe sur la page et ne charge les scripts que dans ce cas. Adapté aux sites où le formulaire est affiché via un shortcode dans le contenu (plutôt que codé en dur dans un template).

Inconvénient: ne fonctionne qu'avec JavaScript (les CSS du plugin doivent encore être désactivées séparément). Nécessite un bundler dans le projet. Le package est minimal (1 étoile sur GitHub), maintenu par un seul développeur: pour la production, vous devriez le forker et vérifier la compatibilité avec les mises à jour de CF7.

Que choisir: comparaison des trois approches

Critère

defer via hook

Constantes + template

lazy-cf7-assets

Économie de trafic

❌ non

✅ totale

✅ totale (JS)

Protection face aux mises à jour de CF7

✅ oui

✅ oui

nécessite vérification

Pas de modification de template requise

✅ oui

❌ non

✅ oui

Désactive les CSS

❌ non

✅ oui

❌ non

Complexité de mise en œuvre

faible

moyenne

moyenne

Shortcode de formulaire dans le contenu

✅ fonctionne

❌ difficultés

✅ fonctionne

Si votre formulaire se trouve sur une seule page dans un template dédié, utilisez la méthode 2 (méthode officielle). Si le site utilise un bundler moderne et que vous pourriez avoir plusieurs formulaires à différents endroits, la méthode 3 (lazy-cf7-assets). Si vous avez besoin d'une solution «tout de suite» sans modifier les templates, la méthode 1 (defer), mais gardez ses limites à l'esprit.

Une précaution importante: après l'un ou l'autre de ces changements, vérifiez impérativement que le formulaire s'envoie, que la validation fonctionne, que reCAPTCHA n'est pas cassé et que les styles n'ont pas bougé. Ouvrez la page avec le formulaire en navigation privée, remplissez et envoyez un message de test avant et après.

⁉️🤔 Questions fréquentes

Pourquoi CF7 charge-t-il les scripts sur toutes les pages?

Le plugin ne peut pas savoir, au moment du chargement de WordPress, si une page donnée contient un shortcode de formulaire. WordPress assemble la page plus tard, alors que la file d’attente des scripts est déjà constituée. Le développeur Takayuki Miyoshi l’explique dans la documentation officielle: il est techniquement impossible de détecter la présence d’un shortcode avant le hook wp_head. Une approche conservatrice a donc été choisie, celle du chargement systématique. Il s’agit d’une décision architecturale délibérée, pas d’un bug: le plugin sacrifie la performance au profit d’un fonctionnement garanti. La charge de l’optimisation est transférée au développeur du site.

Le formulaire va-t-il cesser de fonctionner si je désactive le chargement global?

Non, si vous réactivez soigneusement les scripts sur les pages nécessaires. Le formulaire perdra la soumission AJAX et la validation côté client uniquement sur les pages où les scripts ne sont pas inclus. C’est pourquoi l’étape 2 (restauration des scripts) est obligatoire: ne vous arrêtez pas à WPCF7_LOAD_JS = false. Vérifiez l’ordre des appels: wpcf7_enqueue_scripts() doit intervenir avant wp_head(), pas après. Et assurez-vous que reCAPTCHA n’entre pas en conflit avec un chargement différé.

La méthode des constantes fonctionne-t-elle avec CF7 6.x?

Oui, les constantes WPCF7_LOAD_JS et WPCF7_LOAD_CSS sont pleinement prises en charge dans la version actuelle 6.1.6 (voir le journal des versions officiel). Tout au long de l’historique du plugin, de la version 3.9 à l’actuelle 6.x, ces constantes n’ont jamais été déclarées obsolètes. Il s’agit de la méthode la plus stable et la mieux documentée pour gérer le chargement.

Que faire si j’ai plusieurs formulaires à différents endroits?

Si les formulaires sont disséminés sur différentes pages via des shortcodes dans le contenu (plutôt que dans des templates), la méthode officielle avec les templates est peu pratique. Utilisez soit lazy-cf7-assets (méthode 3), soit le plugin Conditionally Load CF7: il ajoute un réglage dans l’administration permettant de choisir pour quelles pages ou quels types de contenu les scripts doivent être chargés, et fonctionne sans modification de code.

Trois lignes de code contre des dizaines de requêtes

Le problème «CF7 charge les scripts partout» existe depuis aussi longtemps que le plugin lui-même, et en plus de 10 ans le développeur n’a pas modifié le comportement par défaut, car c’est un compromis entre simplicité et performance. Mais un compromis, pas une fatalité.

La voie la plus sûre est la méthode officielle avec les constantes et les templates. Elle supprime les scripts et les styles du plugin de toutes les pages sauf celles où ils sont nécessaires, et ne casse rien lors des mises à jour. Si votre site utilise une stack moderne avec un bundler, intéressez-vous à lazy-cf7-assets. Si vous avez besoin d’une solution rapide sans modifier les templates, le chargement différé via le hook clean_url vous apportera des gains mesurables dès aujourd’hui.

Testez votre site via PageSpeed Insights avant et après: réduire le nombre de requêtes bloquantes de 1 ou 2 unités et économiser 10 à 30 Ko par page peut améliorer le score Performance de 2 à 5 points, en particulier sur les appareils mobiles.