A l'heure où la vitesse de navigation est un des facteurs les plus importants pour nos sites et blogs alors que ceux-ci se remplissent de plus en plus de fonctionnalités pour nos visiteurs, toutes les méthodes sont bonnes pour gagner ces précieuses millisecondes.
Voici une petite astuce que je viens de trouver qui va donner un petit coup de boost à votre site WordPress, sans pour autant sacrifier une quelconque fonctionnalité.
Je ne sais pas pour vous, mais de mon côté le fichier functions.php de mon thème a plutôt tendance à devenir obèse au fil de mes personnalisations. Il suffit de jeter un œil à mon article sur la personnalisation de l'administration de WordPress pour voir les lignes de code faire des bébés. Il ne s'agit pas seulement du poids du fichier, mais surtout de toutes ces fonctions que devra lire WordPress à chaque chargement de page, même s'il n'en a pas besoin dans l'instant présent.
Mon idée consiste à diviser ce fichier functions.php en plusieurs parties : une partie commune à tous le site, une partie réservée à l'administration, et une uniquement pour le front-end. On peut même imaginer d'autres parties selon ce que vous avez mis dans votre fichier functions.php.
Structurer le code
La première chose à faire est d'étudier le code présent dans notre fichier functions.php pour voir ce qui est utile uniquement pour l'administration, uniquement pour le front-end, ou aux deux. Ce sera en fait la partie la plus difficile, surtout si on a ajouté du code sans trop savoir comment il fonctionne. Ensuite il suffira de séparer ces parties en se basant sur la condition is_admin(). Avant tout, je vous conseille de sauvegarder votre fichier original dans un coin.
Exemple :
1 2 3 4 5 6 7 8 9 | <?php
// Code utile partout
if (is_admin()) {
// Code utile uniquement dans l'administration
} else {
// Code utile uniquement dans le front-end
}
?> |
Déjà, rien qu'en faisant ça, vous devriez sentir une différence dans le temps de chargement de vos pages.
NOTA : La page de login n'est pas considérée comme faisant partie de l'administration. Toutes les personnalisations concernant cette page devront se trouver dans la partie else.
NOTA 2 : Les fenêtres "média", c'est à dire les fenêtres qui s'ouvrent lorsque l'on clique sur l'un des boutons situés au-dessus de l'éditeur visuel ou html (pour mettre une image à la une dans un article par exemple). Je ne sais pas si c'est valable pour toutes ces fenêtres "média", mais j'ai un plugin qui utilise une telle fenêtre pour insérer du contenu dans mes articles, et je me suis rendu compte que dans cette fenêtre is_admin() me renvoie false. Plutôt étrange.
Diviser pour mieux régner
Allons encore plus loin et créons un fichier functions.php par partie, et utilisons seulement ceux dont nous avons besoin.
Pour cela nous allons utiliser une fonction apparue avec WordPress 3, très utile lors de la conception d'un thème WordPress, et nous allons légèrement détourner son utilisation. Il s'agit de get_template_part(). C'est tout simplement une sorte de require() php.
D'abord nous avons besoin de créer les fichiers. Nous avons déjà functions.php, qui servira pour le code commun à tout le site. Créez les fichiers functs-adminonly.php et functs-frontendonly.php qui serviront respectivement pour l'administration et le front-end.
Ensuite, copiez tout ce qui est à l'intérieur de la condition is_admin() et collez le dans functs-adminonly.php. Même chose pour le front-end : copiez tout ce qui est à l'intérieur du else et collez le dans functs-frontendonly.php. Pour finir, il suffit de remplacer le code dupliqué par des get_template_part() avec les paramètres adéquats dans functions.php.
NOTA : J'ai délibérément appelé les fichiers functs-XXXXX.php au lieu de functions-XXXXX.php. Si vous avez regardé la page du codex réservée à cette fonction (en lien plus haut), vous pouvez voir sous la partie "Examples" que la fonction va d'abord chercher le fichier functions-XXXXX.php, et si elle ne le trouve pas elle va chercher le fichier functions.php à la place, et l'inclure. Donc si votre functions-XXXXX.php disparait pour une raison ou pour une autre, functions.php va s'inclure dans lui-même à l'infini, et par la même occasion, déclarer des fonctions déjà existantes. Bref, le site sera en croix. En appelant nos fichiers functs-XXXXX.php on contourne ce problème puisque functs.php n'existe pas.
Si la fonction ne trouve aucun fichier, elle va générer une erreur et stopper le script php. Du coup, il n'est pas idiot de créer un fichier functs.php vide, et par la même occasion, mettre le code commun en premier dans functions.php, et le test is_admin() à la fin du fichier.
functions.php :
1 2 3 4 5 6 7 8 | <?php // Code commun à tout le site if (is_admin()) get_template_part( 'functs', 'adminonly' ); else get_template_part( 'functs', 'frontendonly' ); ?> |
functs-adminonly.php :
1 2 3 | <?php // Code uniquement pour l'administration ?> |
functs-frontendonly.php :
1 2 3 | <?php // Code uniquement pour le front-end ?> |
[update]
Plutôt que de créer un fichier de fallback functs.php vide, pourquoi ne pas y ajouter une alerte qui nous préviendrait dans l'administration que quelque chose foire? Avec le hook suivant, nous aurons une alerte sur fond rouge en haut de toutes les pages de l'administration, dès lors qu'un des deux fichiers manquera à l'appel.
functs.php :
1 2 3 | <?php add_action( 'admin_notices', create_function( '' , "echo '<div class=\"error\"><p>Attention - L\'un des fichiers functs-xxxxx.php de votre thème n\'a pas été trouvé. Vérifiez les fichiers de votre thème.</p></div>';" ) ); ?> |
Mais il faut aussi vérifier que le ficher pour le front-end existe bien, car dans l'admin, on n'essaie pas de l'inclure, donc il ne fera pas de fallback vers functs.php.
functions.php :
1 2 3 4 5 6 7 | if (is_admin()) {
get_template_part( 'functs', 'adminonly' );
if ( !file_exists(TEMPLATEPATH.'/functs-frontendonly.php') && file_exists(TEMPLATEPATH.'/functs-adminonly.php') ) {
get_template_part( 'functs' );
}
} else
get_template_part( 'functs', 'frontendonly' ); |
[update]
Astuce bonus : dans le fichier functions.php, utiliser des is_page(), is_single() ou autre, directement ne fonctionne pas (car au moment où le fichier est "lu", WordPress ne sait pas encore si nous nous trouvons dans une page, un article, ou autre). Il faut donc utiliser un hook :
1 2 3 4 5 | function single_setup() {
if (is_single())
get_template_part( 'functs', 'single' );
}
add_action( 'template_redirect', 'single_setup' ); |
Ce qui donne au final pour functions.php :
functions.php :
1 2 3 4 5 6 7 8 9 10 11 12 13 | if (is_admin()) {
get_template_part( 'functs', 'adminonly' );
if ( (!file_exists(TEMPLATEPATH.'/functs-frontendonly.php') || !file_exists(TEMPLATEPATH.'/functs-single.php')) && file_exists(TEMPLATEPATH.'/functs-adminonly.php') ) {
get_template_part( 'functs' );
}
} else {
get_template_part( 'functs', 'frontendonly' );
function single_setup() {
if (is_single())
get_template_part( 'functs', 'single' );
}
add_action( 'template_redirect', 'single_setup' );
} |
Conclusion
Voilà une méthode assez simple que j'ai testé ici-même, et je dois dire que j'ai vu une différence. Certes cela ne va pas diviser par deux vos temps de chargements mais le gain n'est pas du tout négligeable.
Points positifs :
- Le nombre de lignes de code lues a drastiquement diminué : nous évitons à WordPress de lire des fonctions qui ne lui sont pas utiles à un moment donné.
- Le poids des fichiers chargés : de 48ko pour le fichier functions.php, je suis passé à 6+30=36ko pour le front-end et 6+12=18ko pour l'administration (ok, la différence n'est pas énorme).
- La clarté du code : en séparant en plusieurs fichiers, je trouve qu'il est plus facile de se repérer.
Points négatifs :
- La première étape qui consiste à séparer son code en trois parties est la plus difficile. Le tout est de ne pas se planter à ce moment et de vérifier ensuite que tout fonctionne correctement.
- L'astuce ne sera efficace seulement si le fichier functions.php original est assez conséquent, sinon la différence sera imperceptible.
See ya!









36 commentaires
Salut !
Merci beaucoup pour cette excellente astuce que je n'avais pas encore croisé sur le net !
Je fais la même chose pour mes scripts mais je n'avais pas pensé le faire pour notre sympathique functions.php
bravo !
PS: Je découvre ton site en même temps que cet article et je suis sous le charme... J'adore !!! il est superbe !!!
Au plaisir de te lire !
:lol:
++
Billboc
Salut.
Je suis comme toi, on fait souvent des include ou require en php, mais je n'avais encore jamais pensé à le faire pour functions.php. En plus, en ce moment je suis un peu dans une phase optimisation/sécurité, ceci explique peut-être cela :roll:
Effectivement, je n'ai pas encore vu cette astuce trainer sur le net, et maintenant je me dis "Mais pourquoi on n'y a pas pensé plus tôt!?" ^^
Merci pour ton commentaire et les compliments :)
Oh oh oh, de bonnes idées à tester. Je suis sensible aux arguments vitesse et clarté du code. Je vais tenter.
Merci pour l'astuce.
il y a une petite erreur dans le code.
Ce n'est pas && mais && sinon on obtient l’erreur suivante:
Parse error: syntax error, unexpected ';' in ...
Mais j'ai toujours un probleme. Même après la correction de cette petite erreur, coté blog j'ai un grande page blanche (pas coté admin)
Bonjour,
la différence se mesure en secondes ou moins ? Je très intéressé par votre méthode car je trouve toujours WP un poil trop long.
Que pensez-vous du chargement de mon blog (WP super cache activé) ? Je suis avec un hébergement mutualisé d'OVH.
Merci et très bon article que je n'ai pas hésité à relayer sur Twitter !
Bonjour.
Le gain va dépendre de la taille de votre fichier functions.php : plus il sera fourni, plus le gain sera important. Ainsi il ne sera pas toujours utile d'utiliser cette astuce. De mémoire, je crois que j'ai gagné quelque chose comme une demi seconde (comme j'ai fait pas mal de changements dernièrement, je ne suis plus sûr de rien). A noter que je n'utilise aucun plugin de cache ;)
Je suis allé faire un tour sur votre site, et honnêtement, je trouve qu'il tourne très bien (en plus sur un mutualisé). Il dispose de pas mal de fonctionnalités qui habituellement ralentissent l'affichage d'une page, et pourtant je n'ai pas remarqué de blocage notable (et pourtant je navigue avec Firefox 5). Le plus important (à mon sens) étant que le contenu de la page s'affiche le plus tôt possible, le reste se chargeant ultérieurement. Cela passe bien sûr par tout un tas de choses, mais à priori ça me semble déjà très bien géré :)
Merci pour le commentaire et le tweet ;)
Bonjour,
j'ai regardé le fichier fonction.php (qui se trouve dans le thème, c'est bien ça ?) et j'ai lu qu'il pesait environ 15 000 octets.
Est-ce beaucoup ?
Bonjour.
Oui c'est bien celui là. 14ko à 15ko ce n'est pas énorme, le gain risque d'être léger, ça va dépendre si son contenu concerne la partie front-end ou l'administration.
Ce serait moi, la première question que je me poserais c'est "Est-ce que je m'y connais assez pour modifier ce fichier?". Si oui, alors pourquoi pas, si non, ça ne vaut pas le coup de s'embêter pour si peu et de risquer un quelconque problème que je ne saurais peut-être pas réparer.
Je vais rester comme cela, pas de prise de risque !
Merci.
Il y a une coquille ce n'est pas && mais && car sinon on obtient une erreur.
Même apres avoir corrigé cette coquille, j’obtiens une page blanche coté blog (pas coté admin)
Salut.
En effet, pour le && il s'agissait d'une erreur d'interprétation de mon plugin de colorisation syntaxique (encore en bêta-test), le problème est réglé.
Concernant ta page blanche, tu as une erreur renvoyée par php ou seulement... du blanc? Peut-être qu'un court passage en mode debug à l’abri des yeux indiscrets pourrait aider. De mon côté je n'ai aucun problème avec cette astuce, peut-être que tes fonctions ne sont pas où elles devraient être (côté admin, côté front-end, pour les 2). Sans plus d'infos, je ne saurais t'aider :/
A+
PS : la page blanche est souvent le résultat d'un appel de fonction non définie, à vérifier.
Je me suis dit "super intéressant" et je me suis rendu compte que mon function.php ne faisait que 4ko. Bah oui, j'ai beaucoup de plugins d'installés :-)