Drupal 8 - Gestion du cache - Introduction

05/02/2019

Drupal 8 possède nativement un système de cache assez performant. En effet, de base, Drupal 8 met en cache la plupart des contenus. De cette manière, les rendus sont très nettement moins coûteux, et les temps de requêtes sont considérablement diminués puisqu'on ne repasse pas systématiquement dans tout le processus de recherche, de calcul et de rendu des données (c'est le principe du cache...). 

Ce système est donc performant mais peut paraître assez déroutant lorsqu'on a des considérations de contenus dynamiques.

Dans cet article je vais vous présenter les 3 points qui permettent d'appréhender le cache correctement pour savoir quand utiliser telle ou telle méthode de cache.

 

Page Cache ou Dynamic Page Cache

Par défaut, lors d'une installation de base de Drupal 8, deux modules de cache sont activés. Il s'agit de "Dynamic page cache" et "Page Cache", mais qu'elle est la différence entre les deux ? 

Après quelques recherches, il semblerait que ces deux modules permettent de gérer des caches par contexte, à ceci près que le "Page cache" ne gèrerait que le contexte utilisateur, voire uniquement le contexte utilisateur anonyme, donc une URL = un rendu.
"Dynamic page cache", quant à lui, est capable de gérer des contextes différents pour une même URL. Ce qui nous permet donc de gérer des parties de la page dynamiquement, en fonction des droits d'utilisateurs, de paramètres d'url ou n'importe quel autre contexte. Je vous renvoie vers cette page qui explique plus précisément les comportements de ces deux modules : https://wimleers.com/article/drupal-8-dynamic-page-cache

Pour résumer "Page Cache" sera suffisant, et plus performant pour les sites simples avec des données statiques. En revanche dès lors qu'on va avoir des parties de pages avec des données dynamiques on va préférer "Dynamic Page Cache", même si celui-ci va demander plus de ressources.

Les deux modules peuvent théoriquement vivre ensemble, mais cependant, personnellement, je préfère n'activer que celui qui est nécessaire au projet. En effet, le "Page Cache" peut rendre inefficace le "Dynamic Page Cache".

 

Les contextes de cache

Comme dit précédemment, Drupal permet de générer des caches différents selon les contextes via le module "Dynamic Page Cache".

En gros il s'agit de mettre en cache des versions différentes d'une même entité, selon le contexte. Un exemple de contexte est celui de la langue. Le rendu d'une entité ne sera pas le même dans des langues différentes, donc les éléments mis en cache seront différents selon la langue courante. 

Il existe de nombreux contextes de cache fournis par différents modules de Drupal 8. Il est possible d'indiquer à un élément qu'il dépend de plusieurs contextes de cache. Ainsi, à chaque fois que l'élément est rendu, Drupal va regarder l'ensemble des contextes desquels il dépend, et vérifier l'existence d'un rendu déjà généré correspondant à l'ensemble de ces contextes. Si un seul contexte change, Drupal régénère un cache. 

C'est pourquoi il faut être prudent et ne pas ajouter des contextes de cache inutilement. En effet, plus vous ajoutez de contextes, plus vous générez de cache, donc plus vous chargez votre base de cache, et ceci peut avoir un poids conséquent.

Prenons par exemple le contexte "url.query_args". Celui-ci va générer autant de cache de rendu que d'ensemble de paramètres d'URL appelé. Autrement dit, pour chaque URL contenant des paramètres, vous allez générer un cache, et ce, peu importe si vous utilisez ce paramètre ou pas dans votre rendu. N'importe quel utilisateur qui aura envie d'appeler votre page en ajoutant un paramètre à l'URL générera un doublon de cache inutile.

Donc attention à bien cibler votre besoin. Plutôt que définir un contexte sur l'ensemble des paramètres d'url, définissez plutôt un contexte sur le paramètre d'URL qui va avoir une incidence sur votre rendu (ou plusieurs contextes pour plusieurs paramètres). 

Juste pour le fun, vous trouverez probablement, énormément d'éléments sur le net sur l'ajout de contexte de cache à votre entité. Vous pouvez les gérer directement dans les classes de vos entités custom en redéfinissant la méthode getCacheContext (https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21Entity.php/function/Entity%3A%3AgetCacheContexts/8.2.x). Ou vous pouvez les définir directement dans les build array des entités, donc dans les preprocess :

function my_module_preprocess_node(array &$variables){
  // Ajout du contexte sur le paramètre d'URL search.
  $variables['#cache']['contexts'][] = 'url.query_args:search';
}

Vous pouvez également créer vos propres contexte de cache, mais nous verrons ça en détail dans un article futur.

 

Désactiver le cache

Dans certains cas, il n'est pas utile de générer un cache car les possibilités de rendu sont infinies. Prenons l'exemple d'une page de liste d'éléments qu'on peut filtrer selon un nombre important de critères. Supposons que les paramètres du filtre soient passés par url afin que les utilisateurs puissent partager leur sélections. Dans ce cas, est-il utile de générer un cache par combinaison de filtre ? Evidemment non, chaque utilisateur va générer une combinaison de critères de filtre qui lui est propre alors imaginons que chaque combinaison génère un cache... On va rapidement exploser notre base. Et tout ça pour une combinaison qui sera affichée une fois... peut-être un peu plus mais probablement pas suffisamment pour nécessité une mise en cache.
Dans ce cas, il est possible de désactiver le cache. De cette manière, l'ensemble de l'entité qui gère la liste ne sera pas mis en cache et recalculée infiniment. Même les éléments qui ne vont pas changer comme le titre, la description, la liste des filtres etc..

Heureusement pour nous, il existe également la possibilité de ne désactiver le cache que sur une partie de la page, puisque c'est bien ça qui nous intéresse ici : désactiver le cache sur la liste de résultats uniquement. Et pour cela, on utilisera un lazy builder, mais nous détaillerons ça dans un prochain article. Combiné au contexte de cache, on va avoir un outil puissant qui nous permet de gérer du cache ou pas, selon le contexte.

 

Rapidement

Je ne vais pas détailler les éléments suivants, mais sachez que vous pouvez :

- Désactiver totalement les modules de cache (utile pour les phases de développement) : https://www.drupal.org/node/2598914

- Gérer une date d'expiration du cache : https://www.drupal.org/docs/8/api/cache-api/cache-max-age

- Gérer des tags de cache, pour faciliter les invalidations de cache groupées  : https://www.drupal.org/docs/8/api/cache-api/cache-tags

 

 

Ajouter un commentaire

HTML restreint

  • Balises HTML autorisées : <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • Les adresses de pages web et les adresses courriel se transforment en liens automatiquement.
Votre email ne sera pas publié mais permettra à l'administrateur de vous recontacter en cas de problème