# Un tableau statique en mémoire pour éviter de relire deux fois la même donnée

> Sur une même exécution de page, un tableau statique évite de solliciter le cache objet pour une donnée déjà lue plus tôt dans le même chargement.

- Auteur : WordPress Développement
- Publié le : 2023-04-10
- Mis à jour le : 2023-04-10
- Catégorie : Extensions
- URL : https://www.wpmoderne.fr/extensions/tableau-statique-memoire-eviter-relire-donnee/

## L’essentiel

- Une variable statique évite un aller-retour même vers un cache rapide
- Utile quand la même donnée est lue plusieurs fois par page
- Ne remplace pas le cache objet entre deux requêtes différentes

1 300 requêtes de mesure plus tard, le profilage d'une page produit d'une boutique révélait un chiffre curieux : la fonction qui récupère les options d'affichage d'une extension de recommandations était appelée quatorze fois pour générer une seule page. Chaque appel passait par le cache objet WordPress, via `wp_cache_get()`, ce qui restait rapide individuellement, mais l'accumulation de ces quatorze allers-retours pesait sur le temps de génération global, en particulier lorsque le cache objet persistant n'était pas configuré et retombait sur son implémentation par défaut, non persistante entre les requêtes.

Le problème ne venait pas du cache objet lui-même, correctement utilisé, mais d'une hypothèse implicite dans le code : chaque fonction qui avait besoin de ces options supposait être la seule à les demander, et repartait donc systématiquement chercher la donnée plutôt que de vérifier si elle n'avait pas déjà été chargée plus tôt dans le même chargement de page.

## Le cache objet reste sollicité inutilement

`wp_cache_get()` est déjà rapide : sans backend persistant, il lit un tableau PHP maintenu en mémoire pour la durée de la requête ; avec un backend comme Redis ou Memcached, il effectue un aller-retour réseau, généralement de l'ordre de la milliseconde. Le problème n'est donc pas la lenteur de chaque appel pris isolément, mais leur multiplication : quatorze appels à une milliseconde chacun, répétés sur une page qui effectue par ailleurs d'autres opérations coûteuses, finissent par peser sur le total.

Sur ce projet précis, la fonction concernée était appelée depuis le rendu du bloc de recommandations principal, depuis un filtre appliqué au contenu de la fiche produit, et depuis une fonction utilitaire partagée avec la barre latérale : trois points d'entrée différents dans le code, chacun ignorant l'existence des deux autres.

## Un tableau statique comme mémoire locale

> L'essentiel à retenir : Une variable statique évite un aller-retour même vers un cache rapide ; Utile quand la même donnée est lue plusieurs fois par page ; Ne remplace pas le cache objet entre deux requêtes différentes

La correction ne consiste pas à retirer le cache objet, qui reste utile pour partager la donnée entre deux requêtes différentes, mais à ajouter un niveau de mémoire encore plus local : une variable statique à l'intérieur de la fonction, qui ne survit que le temps du chargement de page en cours.

```
function extension_recommandations_get_options() {
    static $options = null;

    if ( null !== $options ) {
        return $options;
    }

    $options = wp_cache_get( 'options_recommandations', 'extension_reco' );

    if ( false === $options ) {
        $options = get_option( 'extension_reco_options', [] );
        wp_cache_set( 'options_recommandations', $options, 'extension_reco', HOUR_IN_SECONDS );
    }

    return $options;
}
```

Au premier appel de la fonction, la variable statique `$options` vaut `null`, ce qui déclenche la lecture via le cache objet (elle-même appuyée sur `get_option()` en cas d'absence). Dès le deuxième appel, dans le même chargement de page, la variable statique contient déjà la donnée et court-circuite totalement l'appel à `wp_cache_get()`.

## Pourquoi ce n'est pas un doublon du cache objet

Une variable statique et le cache objet répondent à deux problèmes distincts, qu'il est utile de ne pas confondre :

| Mécanisme | Portée | Coût d'accès |
| --- | --- | --- |
| Variable statique | Un seul chargement de page | Quasi nul, lecture mémoire directe |
| Cache objet non persistant | Un seul chargement de page | Faible, lecture d'un tableau PHP |
| Cache objet persistant (Redis, Memcached) | Partagée entre requêtes et processus | Aller-retour réseau, de l'ordre de la milliseconde |

La variable statique n'a d'intérêt que lorsqu'une même donnée est lue plusieurs fois dans une seule exécution PHP. Elle n'apporte rien pour partager une donnée entre deux visiteurs ou deux requêtes successives : ce rôle reste celui du cache objet persistant, qui reste indispensable pour éviter de recalculer une donnée coûteuse à chaque nouvelle visite.

## Où poser ce genre d'optimisation

- Repérer les fonctions appelées plusieurs fois par page grâce à un outil de profilage comme Query Monitor, qui affiche le nombre d'appels à une fonction donnée.
- Réserver la variable statique aux données qui ne changent jamais au cours d'un même chargement de page (options, réglages, métadonnées déjà lues).
- Ne jamais appliquer ce motif à une donnée qui pourrait légitimement changer en cours de traitement de la page, sous peine de servir une valeur périmée.

> La règle que je retiens : avant d'accuser le cache objet ou la base de données d'être lente, vérifier combien de fois la même fonction est appelée sur une seule page. Souvent, le vrai gain se trouve dans la suppression de la répétition, pas dans l'accélération de chaque appel.

## En résumé

Un tableau statique en mémoire coûte trois lignes de code et évite des appels redondants, même vers un cache rapide, sur une donnée lue plusieurs fois par une même page. Ce motif ne remplace en rien le cache persistant entre deux requêtes, qui reste un sujet distinct et tout aussi nécessaire à traiter correctement.
