Contact Form 7 est devenu l’un des plugins de référence pour quiconque souhaite construire un formulaire entièrement personnalisable sur WordPress. Comme tout plugin, il tente de répondre à une problématique en englobant un maximum de contextes, aussi, les fichiers JS et CSS qu’il embarque sont insérés sur toutes les pages de votre site par défaut.
La problématique
Charger ces fichiers sur la totalité de vos pages web demande au visiteur des ressources inutiles.
L’impact est moindre sur un visiteur qui possède une bonne connexion internet, mais à l’ère du mobile (entendez par là, mobilité, donc tablette, mini-tablette, smartphone etc.) et des connexions souvent moins bonnes que notre bon vieux 56k, la moindre économie est bonne à prendre.
Je ne sais pas si le problème est commun, mais comme je vois beaucoup d’articles qui proposent de désactiver les fichiers JS et CSS de Contact Form 7 (merci pour l’astuce au passage !), j’en vois beaucoup moins qui proposent de les charger uniquement en cas de besoin, ce qui permettrait de continuer à bénéficier des fonctionnalités et styles de base du plugin.
Une solution ?
Il doit en exister des meilleures, mais pour le moment j’en ai trouvé une qui fonctionne plutôt bien.
Collez ce code à la fin de votre fichier functions.php
.
/**
* Contact Form 7 - Load files only if necessary
*/
if (!function_exists('juiz_wpcf7_dequeue_scripts_styles')) {
function juiz_wpcf7_dequeue_scripts_styles() {
if ( WPCF7_LOAD_JS && WPCF7_LOAD_CSS ) {
global $post;
if ( !strpos($post->post_content, '[contact-form-7') ) {
wp_dequeue_script('contact-form-7');
wp_dequeue_style('contact-form-7');
}
}
}
add_action( 'wp_enqueue_scripts', 'juiz_wpcf7_dequeue_scripts_styles' );
}
Quelques explications s’imposent peut-être.
Les constantes WPCF7_LOAD_JS
et WPCF7_LOAD_CSS
sont définies par le plugin lorsqu’il est activé. Elles retournent true
lorsqu’elles existent, false
si un réglage particulier est fait, et ne sont pas définies si le plugin n’est pas activé.
Du coup mon code propose d’intervenir uniquement si le plugin est activé, et si les fichiers demandent à être chargés.
Le reste du code vérifie si on trouve le shortcode de Contact Form 7 dans le contenu, si ce n’est pas le cas, alors on retire les fichiers du chargement grâce aux fonctions wp_dequeue_script()
et wp_dequeue_style()
.
Il est possible d’être beaucoup plus précis en vérifiant si la constante CSS existe d’une part pour désactiver uniquement CSS en cas de besoin, d’autre part la JS pour ne désactiver que la JS.
Personnellement je ne désactive pas l’un sans l’autre en générale 🙂
Je n’ai pas encore trouvé de problème à cette manière de faire, mais j’ai encore le nez dedans, donc n’hésitez pas à commenter si vous trouvez à redire ! La seule limite c’est le preg_match()
qui s’exécute sur chaque contenu, m’enfin on a rien sans rien.
Merci à jb pour l’optimisation
Excellent, j’ai fait une recherche, à ce sujet, il y a quelques jours… Après plusieurs test de scripts glanés ça et là, j’ai tout simplement abandonné, les solutions proposées n’étant pas très satisfaisantes. Je viens de tester ton script, c’est exactement ce que je cherchais ! Merci beaucoup. Bon boulot.
Salut !
Merci pour ton retour et ravi que ça serve à d’autres qu’à moi :p
Excellente comme astuce : le code est efficace et propre.
Il peut éventuellement y avoir un autre moyen plus performant de faire la même chose : l’ajout de cette information dans la table post_meta lors de l’enregistrement et/ou de la publication de l’article. Et ensuite on pourrait tester la présence de cette meta pour faire le dequeue. Le seul hic, c’est qu’il faudra penser à aller réenregistré chaque article ou page contenant Contact Form 7.
Hello,
Merci pour ta suggestion, j’avais pensé à un truc tordu comme ça également, mais plutôt un enregistrement automatique d’une meta si on trouve le shortcode dans une page, et son retrait si on ne le trouve pas. Cela évite les oublis de l’éditeur du contenu. Mais c’est un peu lourd pour si peux, et checker une meta ou « preg_matcher » un contenu, je ne saurais dire lequel des deux est le plus performant.
J’avais tendance à abandonner ce plugin (pourtant bien foutu) sur les install wordpress justement parce que j’étais contrarié de voir ces deux css/js polluer la waterfall de TOUTES les pages.
Excellente astuce, je partage.
Coucou.
Sympa comme idée. Pour ma part, je ne l’utilise plus depuis des lustres ce plugin, mais en revanche, je serais heureux de trouver une solution similaire en ce qui concerne le chargement d’une CSS de WP-Syntax. Ce plugin balance toujours sa css même si, il n’y a pas d’appel de la fonction. J’ai bien la solution de déménager ses attributs dans ma propre CSS, mais à chaque mise à jour, faut recommencer et de toute manière, encore une fois, ça charge du code pour rien.
Aurais-tu une idée de comment faire ça ?
Hello,
Je ne connais pas WP-syntax ni comment il fonctionne, mais je peux jeter un œil à l’occasion 😉
http://wordpress.org/extend/plugins/wp-syntax/ c’est un traducteur de langage GeSHi pour afficher, donc, du code (PHP, Java…) dans ses articles, et du coup, il met pas mal le bronx côté CSS. J’ai une grosse perte de PageSpeed à cause de lui.
Hello,
D’après ce que j’ai vu le code du plugin est un peu bordélique, et d’ailleurs il semblerait que la dernière version n’utilise plus le JS mais des règles de formatage assez avancées en PHP.
Globalement le code suivant fonctionne sur mes rapides tests :
À coller dans
functions.php
donc 😉Mon code vérifie s’il trouve quelque chose comme « pre lang css(javascript ou php ou html à toi de compléter) », si ce n’est pas le cas alors il ne charge pas la CSS, ni le JS.
C’est probablement améliorable, tu me diras à l’usage.
Bonne soirée.
Oh, bien, merci beaucoup, c’est super sympathique de ta part. Oui, sinon, le plugin est un peu ancien, mais c’est aussi l’un de ceux que je trouve le plus « simple » et fonctionnel, sans rentrer dans un système de machine à gaz. Je l’utilise d’ailleurs depuis plusieurs années, mais j’aurai aimé qu’il soit un peu plus optimisé et un peu plus « léger » du côté du code. Je m’en vais de ce pas rajouter ça dans mes functions 🙂 Encore Merci !
Ah, bon, je reviens vers toi. Apparemment, le css est toujours chargé, comme sur la home où le plugin n’est pas appelé. J’ai testé avec GTMetrix, et je le vois aussi sur Chromium et Firefox. À moins que j’ai un cache surpuissant dans mon système ?
Très bonne astuce seulement ce qui me gène est de garder leur stupide feuille de style qui va sauter à chaque update.
Il faudrait donc séparer cette CSS du plugin donc virer le CSS et rajouter une feuille de style qui se charge uniquement quand le shortcode est utilisé mais que l’on place dans le thème.
Pour cela y a l’astuce de BAW (Julio) sur GeekPress que perso j’utilise beaucoup 🙂
Testé: ça marche :
<code>
function remove_wpcf7_stylesheet() {
remove_action( ‘wp_head’, ‘wpcf7_wp_head’ );
}
add_action( ‘init’ , ‘remove_wpcf7_stylesheet’ );
if (!function_exists(‘juiz_wpcf7_dequeue_scripts’)) {
function juiz_wpcf7_dequeue_scripts() {
if ( WPCF7_LOAD_JS ) {
global $post;
if ( !preg_match(‘#\[contact-form-7#’,$post->post_content) ) {
wp_dequeue_script(‘contact-form-7’);
}
}
}
add_action( ‘wp_enqueue_scripts’, ‘juiz_wpcf7_dequeue_scripts’ );
}
function baw_enqueue_my_script() {
global $post;
if( !$post ) return;
$matches = array();
$pattern = get_shortcode_regex();
preg_match_all( ‘/’ . $pattern . ‘/s’, $post->post_content, $matches );
foreach( $matches[2] as $value ) {
if( $value == ‘contact-form-7’ ) {
wp_enqueue_style( ‘contact-form-css’, get_stylesheet_directory_uri().’/css/wpcf7.css’ );
break;
}
}
}
add_action( ‘wp_print_scripts’, ‘baw_enqueue_my_script’ );
</code<
🙂
oublié un petit truc :
if ( function_exists(‘wpcf7_contact_form’) ) {
if ( ! is_admin() && WPCF7_LOAD_JS )
remove_action( ‘init’, ‘wpcf7_enqueue_scripts’ );
add_action( ‘init’ , ‘remove_wpcf7_stylesheet’ );
}
Pour enlever notre CSS
Merci Julien,
Effectivement cette solution va plus loin en prévoyant des styles perso sur les formulaires.
Personnellement j’inclus ces styles à ma feuille de styles générale pour éviter une requête de plus.
Une autre technique qui marche bien également, en ciblant directement la page qui contient le formulaire de contact :
http://technicallyeasy.net/2010/08/how-to-load-the-contact-form-7-script-for-a-contact-page-only/
Hello,
Sauf que le problème de cette technique c’est que le jour où ton client change le titre de la page… bref, pas très flexible.
@joe: à la rigueur si vraiment tu veux opter pour cette techniques je remplacerais le is_page(‘contact’) par is_page_template(page-form.php’) en disant à ton client d’utiliser le template correspondant quand il veut insérer un formulaire comme ça il pourra changer ses titres.
Mais le problème reste entier concernant les posts. Donc il vaut mieux se baser sur la présence ou non du shortcode
Excellent merci ! J’en avais testé plusieurs et aucun n’apportait vraiment de résultat. Avec ton code ça à l’air de fonctionné selon P3 Plugin Profiler alors je suis super content ! 🙂
C’est cool ça 🙂
Merci pour ton retour.
Bonjour,
Je souhaiterai récupérer la valeur de la checkbox de mon formulaire dans l’email de réception. A savoir si oui ou non la personne à cocher cette checkbox.
Merci
Bonjour,
Ce n’est pas trop l’objet de l’article, mais je vais tout de même répondre : tout est écrit dans la doc de WPCF7 🙂
Dans votre formulaire, si vous avez quelque chose dans ce genre :
[checkbox votre-reponse "Accepter" id:accept]
Vous pouvez récupérer la valeur en entrant dans le champ « corps du message » :
Réponse : [votre-reponse]
Bonne continuation.
Merci pour votre réponse et pour les conseils prodigués sur votre blog.
Bonne journée.
@Geoffrey et @Julien. Vous avez tout à fait raison, moins flexible et moins évolutif. Mais tous les clients ne modifient pas les titres de leurs pages (ou leur ID) en particulier dans le cas d’une rubrique nommée « contact » qui évolue très peu fréquemment (par ex: pour les petits sites vitrines avec une arborescence peu profonde).
« La seule limite c’est le preg_match() qui s’exécute sur chaque contenu, m’enfin on a rien sans rien. »
preg_match() est fait pour utiliser des expressions rationnelles. Si tu veux juste savoir si une chaine est présente, strpos() est bien plus rapide. D’ailleurs c’est indiqué dans la doc de PHP :
« N’utilisez pas preg_match() si vous voulez uniquement savoir si une chaîne est contenue dans une autre. Utilisez dans ce cas les fonctions strpos() ou strstr(), qui sont beaucoup plus rapides. »
C’pas faux, merci pour ton intervention 🙂
Hello
Question stupide mais je colle bien ton code à la fin de mon fiction function de mon thème ? 🙂
Merci
Hello,
Tu peux coller ton code à la fin de ton fichier functions.php de ton thème, oui 🙂
Je ne l’ai pas précisé dans l’article, je vais l’ajouter.
Merci.
C’est bien ce que je pensais…dans ledoute c’est ce que jnai fait 🙂 cool que cela soit ça…
Merci pour l’astuce…j’ai encore tellement de boulot d’optimisation a faire…hum pfffff
🙂
Bon courage pour la suite 🙂
Bonjour,
On pourrait remplacer
if ( !strpos($post->post_content, '[contact-form-7') )
par
if ( !has_shortcode( $post->post_content, 'contact-form' ) )
.Testé, ça marche. Est-ce plus optimal ?
Note : WPCF7 propose un nouveau shortcode
[contact-form]
, sans le 7.Hello,
En effet on peut utiliser également cette fonction. WordPress 3.6 la rajoute (depuis peu donc).
Par contre plus optimal « WordPressement » parlant oui, mais en terme de perf je ne crois pas puisque cette fonction fait un
preg_match_all
.http://core.trac.wordpress.org/browser/tags/3.6/wp-includes/shortcodes.php#L153
Mais c’est de l’ordre du chipotage à mon avis 🙂
Merci pour l’info concernant le renommage du shortcode. Du coup par souci de rétro compatibilité, je préfère ma solution en supprimant le « -7 » en fin de chaîne, cela englobe les deux possibilités.
Bonne journée.
Enfin! une solution qui fonctionne! Merci infiniment.
Salut,
Merci pour ta soluce, qui marche… bien… trop peut-être… 🙂
Je ne pige pas ce qui cloche dans ma config mais ton code me vire bien les JS et CSS des pages… MAis il me les vire également de ma page contact 🙂
J’ai bien vérifié les codes… ca roule.
Donc là je sèche. On est d’accord que ca marche aussi bien sur les posts que sur les pages ?
Moi il est collé sur une page.
merci
a+
Hello,
Peux-tu vérifier ce que retournent WPCF7_LOAD_JS et WPCF7_LOAD_CSS (en faisant un var_dump() ).
Merci
quelque soit la page, une page, un post et même la page du formulaire, j’ai : « bool(true) » pour les 2 valeurs
Tu as remplacé le
[contact-form-7
par le bon shortcode ? Il est possible que contact form utilise désormais le shortcode[contact-form
sans le 7 derrière.Je parle bien de le remplacer dans le code que je fournis.
Bin je pense que c’est bon, voilà mon code d’appel :
[contact-form-7 id="329" title="Formulaire de contact 1"]
C’est là que je ne pige plus
Je sèche, faudrait que je vois ça en direct sur ton installation. Je te laisse m’envoyer un mail via le formulaire du blog ? Merci 🙂
Super merci Geoffrey ça m’a bien servi 🙂 ce script peut servir pour d’autres plugins ? j’ai le plugin responsive lightbox qui appelle 2 css sur toutes mes pages et je trouve pas le moyen de les désactiver.
Si tu as une petite idée je suis preneur.
Et merci encore pour cette article 😉
Hello,
Il est possible de créer ce genre de désactivation pour d’autres plugins, mais il faut voir d’abord comment est coder le plugin et dans quelles conditions désactiver/activer le chargement des fichiers utiles.
Bonne soirée 🙂
Merci pour ce tutoriel qui ma permis de augmenter de 1% sur gt metrix. Ce dernier me demandé de corriger l’url de contact form 7 en me précisant que l’adresse n’existè pas et en mettant votre code dans mon function.php cela a supprimé l’erreur sur gt metrix.
Par contre dans le même onglet d’erreur j’en ai d’autre a corriger cela ce situe dans le thème cette fois ci ,du coté css qui faut supprimer, savez vous comment je peux adapter votre code pour corriger les erreurs que gt metrix me donne ?
Voici le résumé chez gt metrix:
Avoid bad requests:
wp-content/themes/virtue/assets/js/main.js
wp-content/themes/virtue/assets/js/plugins.js
wp-includes/js/masonry.min.js
Hello,
Hélas il faut analyser le thème et voir précisément pourquoi ces erreurs apparaissent. Je ne peux pas te fournir de solution aussi simplement.
Ces fichiers semblent simplement ne pas être accessibles.
Bon courage.
Ce n’est pas grave au moins tu répond a mes question et en quelque sorte tu me donne des pistes, je vais donc vérifier quel est la cause de ce blocage.
Connait tu le script crawlprotect ? Je me sert de ce script pour mon blog et j’aimerais savoir si vraiment il en vaut la peine je te demande cela parce que j’ai l’impression que tu bidouille pas en mal en sécurité.
ps: Bravo pour ton blog quel fusée 97/100 sur google speed et gt metrix et même en version mobile encore bravo.
Hello.
Merci 🙂
Pour la vitesse du blog j’utilise WP Rocket qui fonctionne plutôt bien quand le thème n’est pas trop mal fichu. Ça m’a permis de gagner 2 points sur le score final, c’est peu mais j’avais déjà entrepris pas mal d’optimisations que WP Rocket automatise bien.
Concernant crawlprotect oui je connais, mais c’est parfois difficile dans certains projets web d’automatiser les exceptions sur les requêtes avec des variables dans l’URL. Mais ça reste une bonne protection supplémentaire et un moyen d’identifier les attaques.
Il existe un plugin WordPress ?
Bonne recherche 🙂
Merci pour ta réponse.
Moi je viens d’installer le CDN que 1&1 propose qui est powered by CloudFlare et celui la ma permis de passer à un score de 88/100 à 95/100 sur gtmetrix. Mon problème cité ci-dessus on disparut à savoir « Avoid bad requests: » j’ai 100% .
Il me permet d’activer:
Auto Minify:
CSS, HTML
Rocket Loader™ (Chargement asynchrone JavaScript):
ARRÊT
Mirage™ (chargement d’images intelligent):
ARRÊT
Polish™ (compression d’image)*:
ARRÊT
Railgun™ (chargement rapide de contenu dynamique)
Tout cela en mode actif ce qui me donne le score 95/100 c’est la seul solution que j’ai trouvé pour le moment. Par contre cela commence un peut à m’énerver entre les résultats google speed et gt metrix leur coefficient sont vraiment et extrêmement pas les même.
Salut Geoffrey,
J’ai un soucis survenu depuis l’utilisation de ContactForm7, après avoir enregistré un formulaire, mon navigateur « télécharge » les pages au lieux de les éxecuter, ni-plus ni-moins… : / Je ne sais plus ou cherché.. Un petit coup de main ou juste une idée sur l’origine du problème serait fort appréciable… J’ai pensé que ca venait des script du plugin, mais ca n’en à pas l’air.. PS l’article est super, j’essaye dès que ca remarche!
Mon problème est résolu! Ca venait d’une ligne du .htaccess qui empêchait la compilation des fichiers php.. du coup les navigateurs téléchargent les sources.. bad.. Mais comme tous marche bien maintenant je vais tester ! Merci encore pour les super conseils, depuis des années!! tchuizz
Hello Thomas,
Navré, j’étais en déplacement, je n’ai pas pu répondre plus tôt.
Si jamais tu peux donner ta solution aux autres lecteurs, ça pourrait servir un jour 😉
Merci à toi et bonne continuation.
Bonjour Geoffrey Crofte,
Je vous prie de m’aider car je sèche depuis plusieurs jours. Ma préoccupation est que je veux insérer du code javascript dans un champ SELECT de mon formulaire afin d’afficher le résultat dans un autre champ selon le choix effectué. Mon blocage est que Contact from7 ne reconnait pas le code ajouté dans le html du formulaire. Exemple de mon code ( [select* Etudes onChange=’Choix(this.form)’ placeholder « * Niveau d’étude actuel » « CAP » « Seconde » « Première » « BAC » « BAC +1 » « BAC +2 » « BAC +3 » « BAC +4 » « BAC +5 »])
Je te prie de regarder s’il y a une astuce qui puisse fonctionner. Merci par avance
Bonjour 🙂
C’est censé fonctionner d’une manière ou d’une autre.
Il faut penser à vérifier que Javascript s’exécute bien quand le contenu du DOM est disponible.
Il y a la même interrogation ici je crois : https://stackoverflow.com/questions/20448056/how-to-add-custom-javascript-function-in-contact-form-7-wordpress et la première réponse me semble viable.
Bon courage 🙂