Accueil > WordPress > Extensions WordPress > WP Deferred Javascript : chargez vos scripts en asynchrone

WP Deferred Javascript : chargez vos scripts en asynchrone

Publié le 5 février 2013 Extensions WordPress

C'était une idée qui trottait dans la tête de Willy Bahuaud depuis quelques temps déjà : améliorer le temps de chargement de WordPress en chargeant tous les scripts de manière asynchrone, c'est à dire en même temps que le reste de votre page, sans la bloquer.

Ni une ni deux, nous nous sommes mis à codé un peu et voici le résultat: le plugin WP Deferred Javascript.

WP Deferred Javascript
WP Deferred Javascript : un plugin qui vous veut du bien

A quoi sert le plugin ?

Notre plugin a un objectif simple : améliorer le temps de chargement des sites WordPress. Pour cela, il se concentre sur une chose : le chargement asynchrone des scripts, permettant un rendu plus rapide de la page sans que celle-ci ne soit bloquée par le chargement de ceux-ci.

Je ne vais pas aller dans le détail du code puisque Willy le fait très bien sur son site Wabeo : WordPress et les JavaScripts asynchrones.

En résumé, voici comment cela se passe :

  • Le plugin stocke temporairement les scripts qui devraient être chargés dans le header et le footer.
  • Il empêche WordPress de les charger
  • Il les place tous dans le footer, dans le bon ordre des éventuelles dépendances
  • Il les charge en asynchrone avec l'excellente libraire LABJS.

The core purpose of LABjs is to be an all-purpose, on-demand JavaScript loader, capable of loading any JavaScript resource, from any location, into any page, at any time. Loading your scripts with LABjs reduces resource blocking during page-load, which is an easy and effective way to optimize your site's performance.

Cela vous permettra donc de vous prendre un peu moins la tête sur l'optimisation de vos scripts, comme je l'expliquais dans le tutoriel d'optimisation d'un thème WordPress.

L'installation de WP Deferred Javascript

Le plugin est très simple : installez-le et activez-le, et le tout est joué. WordPress se chargera du reste pour vous.

Attention cependant, car WP Deferred Javascript ne fonctionne qu'avec les scripts correctement ajoutés, c'est à dire ceux avec la fonction enqueue de WordPress. S'ils sont ajoutés de manière brute dans le contenu, ils seront ignorés. Cela vous permettra donc de savoir si vos différents plugins et votre thème est correctement codé.

Théoriquement, tout plugin ou thème doit en effet insérer un script sous la forme suivante :

wp_register_script('monscript', 'url/monscript.js', array('scripts dont je dépend éventuellement'), 'version', false);

wp_enqueue_script('monscript'));}

Et pour les développeurs qui se posent la question, toutes les données insérées avec un localize_script sont correctement prises en comptes par le plugin WP Deferred Javascript.

Par contre, si votre thème a déjà été optimisé comme dans le tutoriel cité un peu plus haut, le plugin ne vous servira à rien (car vous auriez déjà un script unique, minifié et situé dans le footer de vos pages).

Téléchargement

Vous l'aurez donc compris : le plugin Wp Deferred Javascript, c'est :

  • deux auteurs : Willy Bahuaud et Daniel Roch.
  • une librairie de chargement asynchrone Open Source.
  • un meilleur temps de chargement pour votre site WordPress.
  • le meilleur moyen de savoir si votre thème et vos plugins sont bien codés.

Et cela se télécharge ici : WP Deferred Javascript

EDIT : après quelques tests, le plugin peut faire gagner jusqu'à 25% de temps de chargement. Foncez le télécharger ;)

Daniel Roch CEO - Créateur de SEOMIX & SEOKEY

Expert SEO WordPress - Créateur de SeoMix et SEOKEY - Orateur - Auteur de nombreux livres sur le référencement naturel

45 Commentaires

Julio Potier (BoiteAWeb.fr) Le 05 février 2013 à 9h14

Bravo à vous deux pour ce lancement de votre premier plugin, continuez continuez :D
Je ne l'ai pas testé car de toute façon ma v2 est à jeter, mais sur la v3 je teste ça !

Jérémy Le 05 février 2013 à 9h41

Proprement codé. En test sur mon blog perso. J'avais une idée dans ce style, si j'ai 5 minutes, je teste un pti truc et vous file la chose.

Pascal CAMLITI@architecte Marseille Le 05 février 2013 à 10h54

Bravo et merci à vous deux... J'ai mis en place ce jour le Plugin et vais contrôler si cela porte ses fruits.

A priori, cela accélère le chargement (mais est-ce un effet placebo ?) ;)

Il reste plus qu'à tester avec nos outils habituels.

Pierre Le 05 février 2013 à 13h40

Très bien le plugin, je l'ai mis en prod et je pense que je vais l'adopter ;), il donne de bons résultats, généralement je suis pas très fan de plugin quand il s'agit de performance pour un WP mais là bravo.

Julio Potier (BoiteAWeb.fr) Le 05 février 2013 à 14h31

@pascal: pas de placebo possible puisque tu peux faire un véritable test de temps de chargement. Cela ne se calcul pas "à l'oeil" ;)

Aurélien Denis Le 05 février 2013 à 14h46

Hello, je viens de tester sur mon site. Bon vu que j'avais déjà indiqué dans les paramètres de charger les scripts dans le footer je n'ai pas vu de changements.

Mais l'objectif est très intéressant et je vais suivre ça de très près ! :)

Merci.

Willy Le 05 février 2013 à 17h34

@tous Nous avons fait une série de test sur un de nos site (un site est normal, pas de traitement particulier des scripts).

Le résultat se traduit par un gain de 25% sur la vitesse de chargement (peu importe si on a demandé les scripts en haut ou pied de page) :-)

KM Le 05 février 2013 à 17h35

Hello, excellent plugin mais ne semble pas compatible avec Smooth Slider malheureusement :(

Willy Le 05 février 2013 à 23h00

@KM oui bon en fait maintenant ça marche dans la dernière version (1.4) du plugin ^^

Nous n'avions pas relevé ce bug, mais notre script s’exécutait un chouilla de hook trop tôt...

Du coup les scripts qui était ajoutés au tout dernier moment (comme smooth slider qui le fait sur wp_print_scripts) étaient simplement squizzés.

:-)

lereferenceur Le 06 février 2013 à 0h30

On lit partout qu'ils ne faut pas charger nos sites de plugin pour ne pas les ralentir. Et là c'est l'inverse :)

Je vais tester ça sur quelques sites pour voir si je gagne ces 25% ^^

Valentin Le 06 février 2013 à 8h55

Super cette extension !
Par contre, comme KM, lors de mon test hier FlexSlider a également arrêté de fonctionner.

leMoussel Le 06 février 2013 à 9h06

Une autre piste d'évolution/d'optimisation serait d'utiliser les nouvelles fonctionnalités d'HTML 5.

En cela je pense à l'utilisation de l'API HTML 5 "Local Storage" afin de mettre en cache le code JavaScript.

Willy Le 06 février 2013 à 9h22

@Valentin C'ets à dire que lorsque j'active flex slider sur mon site de test (WP 3.5.1), il me mets un message :
Notice: wp_register_script was called incorrectly. Scripts and styles should not be registered or enqueued until the wp_enqueue_scripts, admin_enqueue_scripts, or init hooks..

Je pense que le problème vient de Flex Slider qui enqueue ces scripts directement sur le init :-/ Par contre, on peut suggérer une mise à jour à l'auteur du plugin.

Daniel Roch Le 06 février 2013 à 9h30

On vous avait prévenu que notre plugin vous aiderait à détecter toutes les autres extensions mal codées... ^^

Jean-Paul Le 06 février 2013 à 10h05

Merci pour ce nouveau plugin, nous allons le tester aussi de notre coté

KM Le 06 février 2013 à 10h11

Marche pas mieux pour Smooth Slider et la version 1.4 ne permet plus l'affichage des sous catégories dans l'admin pour ma part... :(

Encore pire... impossible d'éditer un nouvel article ou une page... les élements de mise en forme du texte ne se chargent plus !! Extension désactivée en attendant une mise à jour...

eric Le 06 février 2013 à 10h30

Plugin utile.
Il faut donc partir a la "chasse" aux extensions mal codées (on en trouvera toujours une ici ou la..). Certaines extensions risquent de ne plus fonctionner correctement, il faut donc prendre son temps et bien vérifier.

Juste un détail: les menus contextuels de WP ne fonctionnent plus comme prévu initialement dans l'admin.
Ils ne déroulent plus le menu de navigation. La sélection se fait désormais en 2 étapes au lieu d'une.

Willy Le 06 février 2013 à 10h53

AHHHHH Ca c'est normal...

C'est parce que je suis un boulet -_-

Désolé pour ce problème. Le plugin, suite à la dernière mise à jour, était "à moitié" actif en back office, alors qu'il ne le devrait pas.

On passe donc à la version 1.5 qui corrige ça :-)

"Oy boy !! That escalated quickly !"

KM Le 06 février 2013 à 11h34

Avec la 1.5 Smoooth Slider est toujours dans les choux... :)

Mat Le 06 février 2013 à 12h40

Très sympa comme plug-in, ça fait gagner beaucoup de temps... de chargement, comme au webmaster :)
Par contre, le plug-in ne rentre-t-il jamais en conflit avec W3 Total Cache ? Les mises à jour de ce dernier étant conséquentes, je me demande ce que ça donne (d'ailleurs, si quelqu'un a écrit un papier sur les dernières mises à jour de W3TC, je suis preneur...).

Mmm en fait, après vérif, le plugin fait planter le slider interne de mon thème... Même pour changer manuellement avec les flèches, on arrive sur une URL hashtag...
Pas grave, je garde au chaud jusqu'à une nouvelle mise à jour !

Willy Le 06 février 2013 à 15h20

@Mat @KM En fait il semble que les plugin de slideshow écrivent du javascript directement dans wp_footer() :-/

C'est plutôt une mauvaise pratique car votre script ne peut pas être mis en cache... Il aurait sans doute pu passer par localize script pour coder tout ça mais bon...

Il me semble qu'il n'y ai pas de solutions envisageable pour rendre compatible les deux (à moins de s'adresser aux auteurs de ces plugins).

Tu confirmes Daniel ?

    Daniel Roch Le 06 février 2013 à 15h31

    Je confirme : notre plugin ne fonctionnera qu'à condition que votre thème et vos autres plugins soient correctement codés pour l'ajout des scripts, ce qui en soit est une excellente chose ;)

Geoffrey C. Le 06 février 2013 à 16h06

Arf mince, j'ai une 404 :
http://downloads.wordpress.org/plugin/wp-deferred-javascripts.zip

Merci pour votre boulot, j'attends avec impatience de pouvoir le tester :)

Justement je me demandais comment ajouter async et defer sur les balises de script générées par WordPress, et apparemment ce n'est pas possible (pas de hook prévu).

Crunch Le 06 février 2013 à 22h24

Après une mise à jour de mes sites, notamment une nouvelle version, je l'installe sans hésiter, surtout pour une création made in France !

Bon boulot à vous deux !

Willy Le 07 février 2013 à 15h07

@Geoffrey oui, je suis désolé, on a fait un peu beaucoup de mise à jour cette semaine ^^
Du coup le SVN WordPress n'était pas tout le temps dispo. Là c'est bon maintenant.

C'est vrai que, des fois, WordPress manque de hooks...

@Crunch Merci, et n'hésite pas à nous remonter d'éventuelles incompatibilités avec des plugins :-)

eric Le 07 février 2013 à 21h49

Incompatible avec Tubepress (pour videos Youtube etc..)

Mat Le 08 février 2013 à 15h19

@Willy C'est vraiment dommage, depuis le temps que j'attendais un plug-in comme ça -_-
Et que puis-je faire pour bidouiller le script de mon slideshow afin de le rendre propre et pouvoir utiliser votre petite merveille ? Hormis le slider, rien n'a été perturbé, donc ça m'embêterais de laisser tomber pour ça !

Julie Mazens Le 09 février 2013 à 23h24

Probleme avec Buddypress,

Notamment la fonction de resizing de l'avatar ne fonctionne plus

J'ai temporairement désactivé votre plugin sur les pages buddypress avec l'ajout d'un test bp_is_blog_page() dans :

function you_shall_not_pass() {
        if( ! is_admin() && bp_is_blog_page()  && ! in_array($GLOBALS['pagenow'], array('wp-login.php', 'wp-register.php') ) ) {

Kisss.

Juju Le 10 février 2013 à 14h45

Bonjour, j'ai un soucis avec le plugin sur mon site frakseries.fr. J'ai intégré un slider (slidesjs.com) dans mon thème et avec ce plugin, le slider ne fonctionne plus sur Chrome (les images ne s'affichent pas). Sur Firefox, c'est ok ! Si je désactive le plugin, c'est niquel à nouveau. Je suis sur Linux, pas testé sur Windows.

Pour info, j'ai ajouté les scripts comme ceci :

if( !is_admin() ) {
	wp_deregister_script('jquery');
	wp_register_script('jquery','http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js', false, null, true);
	wp_enqueue_script('jquery');
}

wp_register_script('slides', get_template_directory_uri().'/js/slides.min.jquery.js', array('jquery'), null, 'yes');
wp_enqueue_script('slides');

wp_register_script('shadowbox', get_template_directory_uri().'/js/shadowbox.js', false, null, 'yes');
wp_enqueue_script('shadowbox');

wp_register_script('init', get_template_directory_uri().'/js/init.js', array('shadowbox', 'slides', 'jquery'), null, 'yes');
wp_enqueue_script('init');

Merci à vous !

Matt Le 12 février 2013 à 9h45

Super idée ce petit plug´in, je l'installe tout de suite sur mon WordPress! Merci a tous les deux! :)

funtrolls Le 13 février 2013 à 18h22

Super idée ce petit plug´in, je l’installe tout de suite sur mon WordPress! Merci a tous les deux! :)

Arobasenet Le 22 mars 2013 à 11h54

Je viens de découvrir ce plugin après avoir lu l'article de @choblab sur l'optimisation du chargement WP. Je l'ai installé et jusqu'ici, tout semble aller de mieux en mieux.
Bravo et merci. Je vais de ce pas le faire découvrir à ma Communauté G+.

GeekPress Le 30 mars 2013 à 13h37

Pour info, il existe l'attribut defer qui fait exactement la même chose sans devoir passer par une librairie JS.

En plus, cette attribut est valide IE8+ :)

Voir cette article pour comprendre la différence en defer et async : http://shakup.net/comprendre-et-optimiser-le-chargement-de-vos-scripts/

Geoffrey Le 02 avril 2013 à 10h54

GeekPress : sauf que tu n'as pas la main sur les dépendances, et de mémoire tu ne peux pas rajouter cet attribut sur les scripts chargés par WordPress. Il ne prévoit pas la chose, et il me semble même que ce "problème" fait l'objet d'un ticket ouvert justement.

D'ailleurs l'article que tu proposes ne parle pas suffisamment des limites de defer et async... dommage.

GeekPress Le 02 avril 2013 à 11h31

@Geoffrey : Qu'est-ce que tu entends pas "limite" ?

Après, il faut adapter au cas par cas, perso je n'utilise jamais les wp_enqueue pour mettre les fichiers CSS ou JS. Je place ça directement dans la partie html (plus facile en cas de maintenance par un autre dév et moins de traitement PHP pour si peu de chose).

Julio Potier (BoiteAWeb.fr) Le 02 avril 2013 à 11h47

@GeekPress : ouch, en dur ? comme ça jamais les plugins ne peuvent y toucher ? Tu supprimes une partie de WordPress en faisant ça. La preuve, ici ce plugin ne peut pas bien faire son taf, si tu mets en dur ton jQuery alors un plugin ne peut pas dire "hey je vais mettre celui de google api à la place" car c'est en dur, et pas moyen de minifier tes fichiers en un seul puisque aucun n'est enqueue.
Pourquoi passer à côté de ça !?

GeekPress Le 02 avril 2013 à 11h53

@Julio : Tu le sais, je n'utilise pas de plugin... Et si plugin il y a, je deregister le script ou le style pour l'intégrer dans ma minification.

Oui, c'est chiant pour chaque maj, mais au moins tu as n'as pas 10000 requêtes HTPP suite à l'ajout de 40 plugins...

Willy Le 02 avril 2013 à 11h53

En terme de limite, IE<10 defer les scripts n'importe comment, sans tenir compte des dépendances qu'ils ont entre eux. Du coup ça bug grave...

Voir sur Can I use

Alexis Le 07 juin 2013 à 12h35

Excellent !

Merci beaucoup pour ce plugin. Au début j'ai galéré pour apprendre à charger mes scripts de manière asynchrone sans passer par un plugin. Au final j'ai réussi à charger un script custom player soundcloud en gérant des dépendances, j'étais content, mais je me suis heurté à des soucis avec Wysija newsletters notamment. De + celui ci n'utilisait pas wp_enqueue_script, du coup je ne pouvais pas utiliser votre plugin.

Wysija a été mis à jour tout récemment et c'est ok pour enqueue script (j'ai d'ailleurs vu passer mister Wabeo sur le wordpress codex qui posait la question à monsieur Wysija).

J'ai donc pu installer votre plugin et tout marche au poil. J'ai gagné en moyenne 0.20 secondes de temps de chargement sur 3 tests Webwait, sachant que j'ai déjà pas mal optimisé mes temps de chargement selon les directives google page speed et GTmetrix, donc content :-)

Par contre j'ai juste une question:
- via enqueue_script, on peut demander à ne pas afficher la version des scripts, afin de pouvoir les mettre en cache (si j'ai bien compris ce que me dit GTmetrix)
- j'ai donc passé un paramètre "null" dans wp_enqueue_script pour supprimer le query string "?ver=1.2.3" des scripts
- mais la version s'affiche toujours
=> du coup ma question: est-ce que votre plugin force l'affichage de la version ?

A part ça merci beaucoup !

Willy Le 09 juin 2013 à 22h35

Merci @alexis ,

Effectivement j'ai rencontré des problème avec Wysija, ce qui m'avais un peu étonné car les développeurs sont particulièrement sérieux.

En fait il s'agissait d'un vestige qui a été corrigé dans la dernière version :-) (bravo à l'équipe de Wysija pour la réactivité)

Pour répondre à ta question, le plugin ajoute automatiquement la numéro de version des scripts, et il n'y a pas de moyen simple de le supprimer. Mais ne t'en fait pas : laisser le numéro de version des scripts n'est en aucun cas pénalisant pour la mise en cache, c'est même indispensable !

Si par exemple un script est caché, ou envoyé sur un CDN, le seul moyen de le mettre à jour en cas d'évolution sera de changer l'url. Ca passe donc par un petit paramètre dans l'URL (numéro de version).

Mais je crois que WordPress lui même force un numéro de version. Si on indique false, il retourne tout de même la version de WordPress en paramètre.

Enfin il me semble, mais peut être que je me plante...

Tu confirmes @Daniel ?

Alexis Le 12 juin 2013 à 23h10

Bonjour @Willy

Merci pour cette réponse!

Pour la question sur le numéro de version, j'ai testé voir: j'ai désactivé votre plugin, enlevé les paramètres "null" dans mes register_scripts, et oui WordPress ajoute bien son propre numéro de version le cas échéant

Du coup j'en ai profité pour tester ce snippet qui permet de retirer le numéro de version des scripts et styles:

function _remove_script_version( $src ){
	$parts = explode( '?', $src );
	return $parts[0];
}
add_filter( 'script_loader_src', '_remove_script_version', 15, 1 );
add_filter( 'style_loader_src', '_remove_script_version', 15, 1 );

Il fonctionne -> les numéros de version disparaissent, même sans paramètres "null" dans les register_scripts.

Mais ensuite, quand je réactive WP Deferred Javascripts, les numéros de version reviennent, à la WordPress stayle stadire avec le n° de version de l'installation, et ce même quand y a des Null

Apparemment il y a donc un forçage par WordPress, et aussi par WP Deferred Javascripts. Le côté obscur triomphe donc sur le Null (qui en est un) et sur ma pauvre petite fonction qui du coup est seule à se battre contre plus fort qu'elle ;-)

Pierre Le 12 mars 2014 à 19h26

Bonjour Willy, J'apprécie beaucoup ce plugin. Néanmoins, je rencontre un soucis dans la dernière version de WordPress (3.8).

WordPress charge par défaut une version de jQuery et un fichier complémentaire jQuery-Migrate. Pour cela, il déclare un script sous l'identifiant "jquery" (sans fichier ressource) dépendant de "jquery-core" et de "jquery-migrate".

Ainsi, WP Deferred ajoute au chargement un script qui n'en est pas un, puisqu'il s'agit de la page courante (du fait de l'ajout d'une url vide avec des paramètres).

Le problème n'est pas gravissime hormis que cela génère une erreur d'exécution de javascript. En clair, il faudrait tester que la source de chaque identifiant n'est pas nulle pour éviter de la charger.

Je vais faire une modification en dur en attendant une prochaine mise à jour du plugin.

Ligne 80

'src'   => ( $wp_scripts->registered[ $d ]->src != '' ? add_query_arg( array('v' => $ver ), esc_url( $wp_scripts->registered[ $d ]->src ) ) : ''),

Ligne 136

if($s[ 'src' ] != '') {
				$src	= ( preg_match( '/^\/[^\/]/', $s[ 'src' ] ) ) ? get_bloginfo( 'wpurl' ) . $s[ 'src' ] : $s[ 'src' ] ;
				if( isset ( $s['wait'] ) )
					$output .= '.wait()';
				$output .= '.script("' . $src . '")';
			}

Bonne continuation

Brilloux Le 05 septembre 2014 à 11h56

Merci beaucoup pour ce plugin.
Je viens juste de l'installer et j'ai tout de suite vu une différence.
Très efficace. Un grand Merci!

Jean Pierre Le 19 octobre 2014 à 17h13

merci pour votre contribution à la rapidité de WordPress.

Je rencontre des difficultés d'affichage, dans les faits aucun affichage avec deux catégories de plugins.
Ceux qui permettent une insertion de carte google maps comme wp google maps ou mappress et ceux qui réalisent un slideshow comme easing slider lite et le widget de diaporama de nextgen gallery.
Puis je règler ce problème par moi même car je souhaiterais beaucoup garder votre plugin.

EDIT : Voici une réponse du développeur de Easing Slider Lite
MatthewRuddy wrote:
"Hi @jean pierre, that sounds like an issue with WP Deferred Javascripst and not Easing Slider, as it's likely causing errors within jQuery dependant scripts when deferring them."

    Daniel Roch Le 20 octobre 2014 à 9h19

    En réalité, le souci vient théoriquement de son plugin, ou de son plugin associé aux autres plugins et le thème du site. Notre extension ne fait que charger en différé tous les scripts, mais cela ne fonctionne qu'à la seule condition que chaque plugin et que le thème respecte tous les standards de WordPress pour ajouter proprement des scripts.

Laisser un commentaire

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