Paul Schuhmacher
Durée : 28h
Novembre 2025
Depuis WordPress 2.7
Lâextension de thĂšme sâarrĂȘte Ă la relation parent-enfant. Pas de troisiĂšme niveau (thĂšme petit-enfant impossible)
Renseigner la directive Template: dans
le fichier style.css du thĂšme enfant :
/**
* Theme Name: Mon Theme
* Template: twentytwentyfour
* ...other header fields
*/
Mon Themeétend le thÚmetwentytwentyfour
Activer le thĂšme comme nâimporte quel thĂšme.
Si un thĂšme classique, charger le CSS du
thĂšme parent avec la fonction
get_parent_theme_file_uri():
add_action( 'wp_enqueue_scripts', 'mon_theme_enqueue_styles' );
function mon_theme_enqueue_styles() {
//Charger la feuille de style du thĂšme parent
wp_enqueue_style(
'parent-style',
get_parent_theme_file_uri( 'style.css' )
);
//Charger la feuille de style du thĂšme enfant (override parent)
wp_enqueue_style(
'mon-theme-style',
get_stylesheet_uri()
);
}Dans le thÚme enfant, créer uniquement les templates qui doivent personnaliser ceux du thÚme parent. Pour cela, il suffit de créer le template PHP correspondant dans le thÚme enfant.
Lorsque WordPress va choisir le template Ă utiliser, il va dâabord scanner le rĂ©pertoire du thĂšme enfant. Sâil y trouve le template il lâutilise, sinon il utilise celui du parent (fallback).
On peut ainsi surcharger (override) uniquement un ou plusieurs templates dans le thÚme enfant, tout en bénéficiant des templates du parent.
functions.php
#Ă lâactivation dâun thĂšme, WordPress cherche un fichier
functions.php Ă la racine du thĂšme. Sâil le trouve, il
lâinclut automatiquement (require).
Le fichier functions.php du thĂšme enfant ne
remplace pas (override) celui du thĂšme parent.
Les deux fichiers sont chargés. Le fichier
functions.php du thĂšme enfant est
chargé en premier, celui du thÚme parent en second.
themes/
parent/
functions.php <= chargé en second
style.css
index.php
enfant/
functions.php <= chargé en premier
style.css
index.phpPour construire les bons paths, par exemple lors de
lâinclusion dâun fichier source PHP dans un template ou functions.php,
utiliser la fonction get_theme_file_path()
:
//Par ex, dans functions.php du thĂšme enfant
require_once get_theme_file_path( 'inc/functions-helpers.php' );Utiliser le service du W3C pour valider le markup de vos pages web. Un markup valide est Ă la base dâun rendu de pages web fiable, stable et accessible.
Un markup cassĂ© (câest mal !) :
Consulter les recommandations sur le site officiel :
WP_Query ou
get_posts, pas
query_posts;Techniques dâoptimisation dâapplications WordPress (comme tout site/service web) : obtenir la rĂ©ponse HTTP et la ressource demandĂ©e par le client le plus rapidement possible.
Sur le web, les performances ne se gagnent pas spĂ©cialement sur lâoptimisation du code*, mais sur les accĂšs lecture/Ă©criture (IO) : requĂȘtes HTTP, accĂšs disques, accĂšs DRAM, accĂšs base de donnĂ©es, connexions TCP/IP, etc.
Visionnage recommandé : Performance Optimization - PHP Tour 2016, de Fabien Potencier (créateur de Symfony)
*Dans des langages haut niveau comme PHP, il y a une grande diffĂ©rence entre le code que vous Ă©crivez et le code qui est rĂ©ellement exĂ©cutĂ©, mĂȘme si cela nâempĂȘche pas dâĂ©crire du code efficace, idiomatique et performant.
Optimiser⊠:
Il faut identifier les points de congestion. Inutile dâoptimiser âtoutâ, aveuglĂ©ment.
Utiliser des outils pour monitorer/profiler :
Lire les statistiques :
memory_get_peak_usage) (~ 5-20 MB);Utiliser un serveur web qui supporte la SAPI PHP-FPM (Apache fast cgi, nginx) ou utiliser la nouvelle SAPI FrankenPHP (le futur).
apt install php8.5-fpm php8.5-opcacheĂditer le fichier /etc/php/8.5/fpm/php-fpm.conf :
# Nombre max de processus enfants qui peuvent échouer dans l'intervalle donné
# jusqu'Ă ce qu'on demande au processus maitre de restart (gracefully)
emergency_restart_threshold = 10
emergency_restart_interval = 1mIci le processus maitre redémarre si 10 processus enfants échouent sur une période de 1 minute.
Ăditer le fichier (www est le pool par dĂ©faut, on peut
en créer plusieurs) /etc/php/8.2/fpm/pool.d/www.conf :
#proprietaire du pool (user deploy dédié)
user=deploy
group=deploy
#ip et port sur le quel php fpm accepts inbound request
listen = 127.0.0.1:9000
#Securité : n'autoriser que la machine hote de forward vers le pool
listen.allowed_clients = 127.0.0.1
#nombre max de process enfant qui peut exister chaque instant
#a adapter en fonction de la RAM de la machine (~5M par process, 512mB/5 ~ 51)
pm.max_children = 51
#Le nombre de pools dispos immédiatement qd php-fpm démarre
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
#nb de requetes a traiter max par process avant d'etre libéré et recyclé
pm.max_requests = 1000
#path vers fichier de log pour les requetes qui prennent plus de [n] seconds a process.
#utile pour identifier les bottleneck
#slowlog = /path/vers/log
#request_slowlog_timeout = /âThere are only two hard things in Computer Science: cache invalidation and naming things.â Phil Karlton (Netscape, Xerox Parc)
Spoiler : Lâutilisation du cache nâest pas magique, apporte gĂ©nĂ©ralement des bons rĂ©sultats en terme de performances mais peut poser aussi des problĂšmes si mal configurĂ©. Ne remplace pas de suivre les bons principes de design et dâusage du framework. Permet dâamplifier les performances dâun bon systĂšme.
Cache-Control,
ETag, Last-Modified). Permet de mettre en
cache les pages web cÎté client. Fonctionnalité
fondamentale et centrale du protocole, implémenté dÚs HTTP 1.1
(a sauvé le web, menacé par son propre succÚs !) ;Configuration de la machine virtuelle de PHP (Zend Engine) via des fichiers php.ini (à privilégier) ou des directives (.htacces par ex. avec serveur Apache) :
;Activer l'opcache (mise en cache des opcodes, fichiers PHP compilés)
opcache.enable=1
;Taille mémoire (DRAM) alloué à l'opcache
opcache.memory_consumption=64
;Quantité de mémoire pour les 'interned string', string répétées mise en cache
opcache.interned_strings_buffer=16
; Nombre max de fichiers a stocker dans le cache opcode (> votre nombre de fichiers)
opcache.max_accelerated_files=5000
; Dev : Activé, check si cache est frais tous les revalidate_freq
; Prod : à désactiver (cache des scripts est toujours frais, a mettre à jour au déploiement !)
opcache.validate_timestamps=1
; Fréquence à laquelle valider le cache. A de l'effet uniquement si validate_timestamps est activé En dev, on revalide le cache à chaque fois
opcache.revalidate_freq=0
; Déléguer la libération de la mémoire au gestionnaire de mémoire du zend engine
opcache.fast_shutdown=1
; Utiliser le cache disque en plus du cache ram
opcache.file_cache=/var/cache/opcache
opcache.file_cache_only=0
opcache.file_cache_consistency_checks=1
opcache.enable_cli=1
; Just In Time (JIT) compilation
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=100M
opcache.jit=tracingdisplay_errors = Off
log_errors = On
error_log = /var/log/wordpress.log
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT
file_uploads = On
memory_limit = 64M
post_max_size = 64M
upload_max_filesize = 64M
max_execution_time = 5
zlib.output_compression = On
zlib.output_compression_level = 1
output_buffering=4096
implicit_flush=false
realpath_cache_size=64k ;Cache des path des include (require)
opcache.enable=1
opcache.memory_consumption=64
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=5000
opcache.validate_timestamps=0
opcache.fast_shutdown=1
opcache.file_cache=/var/cache/opcache
opcache.file_cache_only=0
opcache.file_cache_consistency_checks=1
opcache.validate_timestamps=1
opcache.revalidate_freq=0
opcache.enable_cli=1Ă tuner en fonction de lâapplication, son usage et de lâenvironnent
display_errors = Off
log_errors = On
error_log = /var/log/wordpress.log
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT
file_uploads = On
memory_limit = 64M
post_max_size = 64M
upload_max_filesize = 64M
max_execution_time = 60
zlib.output_compression = On
zlib.output_compression_level = 5
opcache.enable=1
opcache.memory_consumption=64
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=5000
opcache.validate_timestamps=0
opcache.fast_shutdown=1
opcache.file_cache=/var/cache/opcache
opcache.file_cache_only=0
opcache.file_cache_consistency_checks=1
; Just In Time (JIT) compilation
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=100M
opcache.jit=tracingReset le cache manuellement (au déploiement, redémarrer le pool) :
systemctl restart php8.5-fpmDepuis un script PHP :
<?php
opcache_reset()Peut ĂȘtre fait avec une autre techno, comme Memcached
Dans wp-config.php :
define('WP_REDIS_HOST', 'redis');
define('WP_REDIS_PORT', 6379);
define('WP_CACHE', true);
//Autres configs importantes : (prod)
//Sécurité : créer un user redis et le renseigner ici sous la forme ['user', 'password']
//define('WP_REDIS_PASSWORD', ['user','password']);
//Fonctionne aussi avec un socket unix ('unix')
//define('WP_REDIS_SCHEME', 'tcp');
//Timeout connexion en secondes
//define('WP_REDIS_TIMEOUT', 1);
//Timeout ecriture/lecture
//define('WP_REDIS_READ_TIMEOUT', 1);
//Max TTL pour les clefs de WordPress en secondes (1h)
//define('WP_REDIS_MAXTTL', 3600);Le plugin Query Monitor permet de lâafficher !
maxmemory). En rajouter si trop de
miss.Calcul du Hit Ratio :
Via un fichier de configuration :
# Mémoire maximale : ajuster selon RAM disponible (ex : 512MB)
maxmemory 512mb
# Politique dâĂ©viction : supprime les clĂ©s les moins utilisĂ©es
maxmemory-policy allkeys-lru
# Optionnel : durée de vie par défaut des clés expirables (TTL par défaut)
# Certaines clés WordPress n'ont pas de TTL, d'autres comme les transients ont leur TTL propreVia la CLI, sans redémarrer Redis :
CONFIG SET maxmemory 512mb
CONFIG SET maxmemory-policy allkeys-lruMonitoring :
redis-cli INFO stats
redis-cli INFO memory
redis-cli MONITORMettre en cache les pages web et les assets (CSS, JS, fonts, icons, etc.)
HTTP permet de définir des politiques de cache via les headers (notamment Cache-Control).
Le cache HTTP peut ĂȘtre placĂ© :
Aucun cache HTTP utilisé par défaut par WordPress!
La majorité des plugins de cache WordPress sont orientés serveur (pas client*) : cache pages HTML sur disque ou mémoire cÎté serveur.
*Les assets (CSS/JS/fonts) sont bien mis en cache cÎté client par contre.
Ces trois couches (cache objet persisté, cache applicatif, opcache) réunies et une fois le cache chauffé :
Et on ne parle pas des gains obtenus en utilisant le pool de processus PHP de PHP-FPM !
Il reste encore à configurer la cache du cÎté de la base de données.
Avec Redis ou Memcached, cette optimisation sera moins critique Ă©tant donnĂ© que le cache objet va rĂ©duire le nombre de requĂȘtes SQL. Mais câest encore une piste dâamĂ©lioration possible !
Pistes : Indexs, cache base de données (query cache), thread pools, optimizing tables, compression, optimizing queries (SQL), data structures optimisations, etc.
Quelques liens utiles :
Bon design, optimisations, maintenance, sécurité et misc.
Combiner les bons plugins pour activer toutes les couches de cache + optimisation des assets (CSS, JS et images)
Installer un plugin dédié à la sécurité du site (peu importe lequel : WordFence, BulletProof Security, etc.) est indispensable !
Voir une liste des meilleurs plugins de sécurité publié par WPMarmite
What else⊠Should be WordPress core⊠Mais lâhistoire en a dĂ©cidĂ© autrement.
Les formulaires : édition des champs, markup et intégration (HTML, CSS), navigation (plusieurs pages ?), validation, traitement et historique.
En avez-vous vraiment besoin ? Souvent⊠oui, car câest du travail (surtout sâils sont complexes, sur plusieurs pages, avec de la validation conditionnelle nĂ©cessitant du JavaScript, etc.) mais vous pouvez aussi dĂ©velopper vos propres formulaires et leurs traitements.