Fermer

décembre 5, 2018

Cacher intelligemment à l'âge de Gutenberg


À propos de l'auteur

Leonardo Losoviz est le créateur de PoP un cadre permettant de créer des sites Web modulaires basés sur PHP et les guidons, et optimisé par WordPress. Il habite à Kuala…
Pour en savoir plus sur Leonardo

Lors de l'optimisation de la vitesse de nos sites Web côté serveur, la mise en cache figure parmi les tâches les plus critiques à effectuer. Dans cet article, Leonardo Losoviz examine une architecture basée sur des composants à rendu automatique et la SSR, ainsi que la manière de la mettre en œuvre pour les sites WordPress via Gutenberg.

La mise en cache est nécessaire pour accélérer un site: au lieu de laisser le serveur créer dynamiquement la sortie HTML pour chaque demande, il ne peut créer le HTML qu'après sa première demande, le mettre en cache et servir la version mise en cache à partir de ce moment. sur. La mise en cache fournit une réponse plus rapide et libère des ressources sur le serveur. Lors de l'optimisation de la vitesse de nos sites côté serveur, la mise en cache figure parmi les tâches les plus critiques à résoudre.

Lors de la génération de la sortie HTML de la page, si elle contient du code avec l'état de l'utilisateur, telle que l'impression d'un message de bienvenue “ Bonjour {{Nom d'utilisateur}}! ”Pour l'utilisateur connecté, la page ne peut pas être mise en cache. Sinon, si Peter visite d'abord le site et que la sortie HTML est mise en cache, tous les utilisateurs recevront alors «Hello Peter!»

. Ainsi, des plugins de mise en cache, tels que ceux disponibles pour WordPress propose généralement de désactiver la mise en cache lorsque l'utilisateur est connecté, comme indiqué ci-dessous pour le plugin WP Super Cache :


 Mise en cache désactivée pour les utilisateurs connus dans WP Super Cache
WP Super Cache recommande de désactiver la mise en cache pour utilisateurs connectés. ( Grand aperçu )

Désactiver la mise en cache pour les utilisateurs connectés est à éviter, car même si la quantité de code HTML associée à l'état utilisateur est minimale comparée au contenu statique de la page, rien ne sera toujours mis en cache. La raison en est que l'entité à mettre en cache est la page, et non les éléments de code HTML particuliers de la page. Par conséquent, en incluant une seule ligne de code qui ne peut pas être mis en cache, rien ne sera mis en cache. C'est une situation de tout ou rien.

Pour résoudre ce problème, nous pouvons concevoir notre application de manière à éviter de rendre le code HTML avec l'état de l'utilisateur côté serveur, et de le rendre uniquement côté client, après avoir récupéré ses données requises via une API (souvent basée sur REST ou GraphQL). En supprimant l'état utilisateur du code rendu sur le serveur, cette page peut ensuite être mise en cache, même si l'utilisateur est connecté.

Dans cet article, nous allons explorer les problèmes suivants:

  • Comment identifier ces sections de Code qui nécessite un état utilisateur, les isoler de la page et les rendre restitués côté client uniquement
  • Comment peut-il être implémenté pour les sites WordPress via Gutenberg?

Gutenberg apporte des composants à WordPress

Comme je l'expliquais dans mon article précédent Implications de la pensée en blocs au lieu de blobs Gutenberg est un éditeur basé sur JavaScript pour WordPress (plus précisément, c'est un éditeur basé sur React, encapsulant les bibliothèques React derrière l’objet global wp ), dont la sortie est prévue pour novembre 2018 ou janvier 2019. Grâce à son interface glisser-déposer, Gutenberg transformera radicalement l’expérience de création de contenu pour WordPress et un peu plus tard dans la Le futur, le processus de construction de sites, le passage de la création actuelle d’une page aux modèles (header.php, index.php, sidebar.php, footer.php), et le contenu de la page via un seul blob de code HTML , à créer des composants à placer n'importe où sur la page, capables de contrôler leur propre logique, de charger leurs propres données et de s'auto-rendre.

Pour apprécier visuellement le changement à venir, WordPress s'en éloigne. :


 La page contient les templates avec le code HTML
Actuellement, les pages sont construites à travers des templates PHP. ( Grand aperçu )

Pour cela:


 La page contient des composants autonomes
Dans un avenir proche, les pages seront construites en y insérant des composants à rendu automatique. ( Grand aperçu )

Même si Gutenberg en tant que constructeur de site n'est pas encore prêt, nous pouvons déjà penser en termes de composants lors de la conception de l'architecture de notre site. En ce qui concerne le sujet de cet article, l’architecture de notre application en utilisant des composants comme unité de construction de la page peut aider à mettre en oeuvre une stratégie de mise en cache améliorée, comme nous le verrons plus loin.

Évaluation de la relation entre pages et composants

Comme mentionné précédemment. , l'entité mise en cache est la page. Par conséquent, nous devons évaluer la manière dont les composants seront placés sur la page afin de maximiser la capacité de mise en cache de la page. En fonction de leur dépendance vis-à-vis de l'état de l'utilisateur, nous pouvons catégoriser les pages dans les 3 groupes suivants:

  1. Pages sans état d'utilisateur, telles que la page «Qui sommes-nous?».
  2. Pages contenant des fragments d'état d'utilisateur, tels que comme page d'accueil lors de l'accueil de l'utilisateur («Welcome Peter!»), ou une page d'archive avec une liste de messages, affichant un bouton «J'aime» sous chaque message peint en bleu si l'utilisateur connecté a aimé ce message. [19659017] Pages naturellement avec l'état utilisateur, dans lequel le contenu dépend directement de l'utilisateur connecté, telles que les pages «Mes messages» des pages «Éditer mon profil».

Les composants, d'autre part, peuvent simplement être classés comme nécessitant un état utilisateur. ou pas. Etant donné que l'architecture considère le composant comme l'unité de construction de la page, le composant a la faculté de savoir s'il nécessite ou non l'état de l'utilisateur. Par conséquent, un composant qui traduit «Welcome Peter!», Sait qu'il nécessite un état utilisateur, alors qu'un composant sait qu'il n'en a pas.

Ensuite, nous devons placer des composants sur la page et, sur la combinaison de la page et du composant nécessitant ou non l'état de l'utilisateur, nous pouvons établir une stratégie appropriée pour la mise en cache de la page et le rendu du contenu à l'utilisateur le plus rapidement possible. Nous avons les cas suivants:

1. Pages sans état d'utilisateur

Elles peuvent être mises en cache sans problème.

  • La page est mise en cache => Elle ne peut pas accéder à l'état d'utilisateur.
  • Les composants, dont aucun n'exigeant l'état d'utilisateur, sont restitués sur le serveur.

 Page sans état d'utilisateur
Une page sans état d'utilisateur ne peut contenir que des composants sans état d'utilisateur. ( Grand aperçu )

2. Pages avec des bits et des morceaux d'état utilisateur

Nous pourrions faire en sorte que la page nécessite un état utilisateur ou non. Si nous faisons en sorte que la page requière un état utilisateur, elle ne peut pas être mise en cache, ce qui est une occasion manquée lorsque la plus grande partie du contenu de la page est statique. Par conséquent, nous préférerions que la page ne requière pas d’état utilisateur et que les composants nécessitant un état utilisateur qui sont placés sur la page, tels que sur la page d’accueil, soient rendus lazy-load: le côté serveur restitue un shell vide. et le composant est restitué à la place du côté client, après avoir récupéré ses données auprès d'une API.

Suivant cette approche, tout le contenu statique de la page sera rendu immédiatement par le biais du rendu côté serveur (SSR), et ces bits. et pièces avec l'état utilisateur après un certain délai par le biais du rendu côté client (CSR).

  • La page est mise en cache => Elle ne peut pas accéder à l'état utilisateur.
  • Les composants ne nécessitant pas d'état utilisateur sont restitués sur le serveur.
  • Les composants nécessitant un état utilisateur sont restitués dans le client.

 Page avec des bits d'état utilisateur
Une page avec des bits d'état utilisateur contient des composants CSR avec état utilisateur et des composants SSR sans état utilisateur. ( Grand aperçu )

3. Pages Naturally With User State

Si la bibliothèque ou l'infrastructure ne permet que le rendu côté client, vous devez suivre la même approche que pour # 2: ne faites pas que la page nécessite un état utilisateur et ajoutez un composant, tel que [19659053]pour s'auto-rendre dans le client.

Cependant, l'objectif principal de la page étant de montrer le contenu de l'utilisateur, le fait d'attendre que ce contenu soit chargé sur une seconde étape n'est pas idéal. Voyons cela avec un exemple: un utilisateur qui ne s’est pas encore connecté accède à la page «Modifier mon profil». Si le site affiche le contenu sur le serveur, étant donné que l'utilisateur n'est pas connecté, le serveur sera immédiatement redirigé vers la page de connexion. Au lieu de cela, si le contenu est rendu dans le client via une API, un message de chargement sera d'abord présenté à l'utilisateur. L'utilisateur ne sera redirigé vers la page de connexion qu'après le retour de la réponse de l'API, ce qui ralentira l'expérience. 19659005] Il est donc préférable d'utiliser une bibliothèque ou une structure qui prend en charge le rendu côté serveur, et nous faisons en sorte que la page nécessite un état utilisateur (la rendant ainsi non cacheable):

  • La page n'est pas en cache => Elle peut accéder à l'état utilisateur .
  • Les composants, nécessitant ou non un état utilisateur, sont restitués sur le serveur.

 Page avec l'état utilisateur
Une page avec un état utilisateur contient des composants SSR avec et sans état utilisateur. ( Grand aperçu )

À partir de cette stratégie et de toutes les combinaisons qu’elle produit, décider si un composant doit être rendu côté serveur ou côté client se résume simplement au pseudo-code suivant:

 si (le composant requiert un état utilisateur et un accès impossible à la page état utilisateur) {
    composant de rendu dans le client
}
autre {
    composant de rendu dans le serveur
}

Cette stratégie permet d'atteindre notre objectif: implémentée pour toutes les pages du site, pour tous les composants placés dans chaque page et pour configurer le site de manière à ne pas mettre en cache les pages qui accèdent à l'état utilisateur, nous pouvons alors éviter de désactiver la mise en cache des pages à chaque fois. l'utilisateur est connecté.

Rendu des composants côté client / serveur via Gutenberg

Dans Gutenberg, les composants pouvant être intégrés à la page sont appelés «blocs» (ou également Gutenblocks). Gutenberg prend en charge deux types de blocs, statique et dynamique:

  • Les blocs statiques produisent leur code HTML déjà dans le client (lorsque l'utilisateur interagit avec l'éditeur) et dans le contenu de l'article. . Il s’agit donc de blocs JavaScript côté client.
  • Les blocs dynamiques en revanche, sont ceux qui peuvent modifier dynamiquement leur contenu, comme le dernier bloc de posts, de sorte ne peut pas enregistrer la sortie HTML dans le contenu de la publication. Par conséquent, en plus de créer leur code HTML côté client, ils doivent également le générer à partir du serveur lors de l'exécution via une fonction PHP (définie sous le paramètre render_callback lors de l'enregistrement du bloc dans le backend via function register_block_type .)

Étant donné que le code HTML avec l'état de l'utilisateur ne peut pas être enregistré dans le contenu de l'article, un bloc traitant de l'état de l'utilisateur sera nécessairement un bloc dynamique. En résumé, grâce à des blocs dynamiques, nous pouvons produire le code HTML d'un composant à la fois côté serveur et côté client, ce qui permet de mettre en œuvre notre stratégie de mise en cache optimisée. Le pseudo-code précédent, lorsqu’on utilisait Gutenberg, ressemblerait à ceci:

 if (le bloc requiert l’état utilisateur et la page ne peut pas accéder à l’état utilisateur) {
    rendre le bloc dans le client via JavaScript
}
autre {
    rendre le bloc (dynamique) sur le serveur via le code PHP
}

Malheureusement, l’implémentation de la fonctionnalité double client / serveur n’est pas sans difficultés: le SSR de Gutenberg n’est pas isomorphe, c’est-à-dire qu’il ne permet pas à une seule base de code de produire la sortie pour les codes client et serveur. Les développeurs auraient donc besoin de maintenir 2 bases de code, une en PHP et une en JavaScript, ce qui est loin d'être optimal.

Gutenberg implémente également un composant mais déconseille de l'utiliser: ce composant n'a pas été pensé pour être amélioré la vitesse du site et une réponse immédiate à l'utilisateur, mais pour assurer la compatibilité avec le code existant, tel que les codes courts.

Comme l'explique la documentation :

«ServerSideRender doit être considéré comme un mécanisme de secours ou hérité, il n'est pas approprié pour développer de nouvelles fonctionnalités.

«Les nouveaux blocs doivent être construits en conjonction avec tous les points de terminaison de l'API REST nécessaires, de sorte que JavaScript puisse être utilisé pour le rendu côté client dans l'édition. une fonction. Cela donne la meilleure expérience utilisateur possible, au lieu d’utiliser PHP render_callback. La logique nécessaire au rendu doit être incluse dans le noeud final, afin que la logique JavaScript côté client et la logique PHP côté serveur ne requièrent qu'un minimum de différences. "

En conséquence, lors de la construction de nos sites, nous aurons besoin de décider de mettre en œuvre la SSR, ce qui accélère la vitesse du site en permettant une expérience de mise en cache optimale et en fournissant une réponse immédiate à l'utilisateur lors du chargement de la page, mais au détriment de la maintenance de 2 bases de code. En fonction du contexte, cela peut en valoir la peine ou non.

Configuration des pages nécessitant un état utilisateur

Les pages nécessitant (ou accédant) à un état utilisateur seront rendues non cachables, alors que toutes les autres pages le seront. Par conséquent, nous devons identifier les pages nécessitant un état utilisateur. Veuillez noter que cela s'applique uniquement aux pages et pas aux points finaux REST, car l'objectif est de rendre le composant déjà présent sur le serveur lors de l'accès à la page, et l'appel des points finaux de l'API REST WP implique d'obtenir les données nécessaires au rendu du composant dans le client. . Par conséquent, du point de vue de notre stratégie de mise en cache, nous pouvons supposer que tous les points de terminaison REST nécessitent un état d'utilisateur et qu'ils n'ont donc pas besoin d'être mis en cache.

Pour identifier les pages qui nécessitent un état d'utilisateur, nous créons simplement une fonction . ] get_pages_with_user_state ainsi:

 function get_pages_with_user_state () {

    retourne apply_filters (
        'get_pages_with_user_state',
        array ()
    )
}

Sur quoi nous implémentons des points d'ancrage avec les pages correspondantes, comme ceci:

 // ID des pages, extraites de l'admin WordPress
define ('MYPOSTS_PAGEID', 5);
define ('ADDPOST_PAGEID', 8);

add_filter ('get_pages_with_user_state', 'get_pages_with_user_state_impl');
fonction get_pages_with_user_state_impl ($ pages) {
    
  $ pages [] = MYPOSTS_PAGEID;

  // "Ajouter une publication" peut ne pas nécessiter l'état de l'utilisateur!
  // $ pages [] = ADDPOST_PAGEID;
    
  retourne $ pages;
}

Veuillez noter qu'il n'est peut-être pas nécessaire d'ajouter l'état de l'utilisateur pour la page "Ajouter une publication" (rendant cette page pouvant être mise en cache), même si cette page nécessite de valider que l'utilisateur est connecté lors de la soumission d'un formulaire pour créer du contenu sur le site. . En effet, la page "Ajouter un message" peut simplement afficher un formulaire vide, ne nécessitant aucun état d'utilisateur. Ensuite, l'envoi du formulaire sera une opération POST, qui ne peut en aucun cas être mise en cache (seules les demandes GET sont mises en cache).

Désactivation de la mise en cache des pages avec l'état utilisateur dans WP Super Cache

Enfin, nous configurons notre application pour désactiver la mise en cache pour les pages qui requièrent l'état de l'utilisateur (et mettre en cache tout le reste). Nous allons le faire pour le plugin WP Super Cache, en mettant en liste noire les URI de ces pages dans la page des paramètres du plug-in:


 Les paramètres de WP Super Cache pour désactiver la mise en cache Chaînes sur liste noire
Nous pouvons désactiver la mise en cache des URL contenant des chaînes spécifiques dans WP Super Cache. ( Grand aperçu )

Ce que nous devons faire, c'est créer un script qui obtienne les chemins d'accès pour toutes les pages avec l'état utilisateur et le sauvegarde dans le champ de saisie correspondant. Ce script peut ensuite être appelé manuellement ou automatiquement dans le cadre du processus de déploiement de l’application.

Nous obtenons d’abord tous les URI des pages avec l’état utilisateur:

 function get_rejected_strings () {

  $ lost_strings = array ();
  $ pages_with_user_state = get_pages_with_user_state ();
  foreach ($ pages_with_user_state as $ page) {

      // Calcule l'URI de cette page dans la liste des chaînes rejetées
      $ path = substr (get_permalink ($ page), strlen (home_url ()));
      $ rejetée_strings [] = $ chemin;
  }

  return $ denied_strings;
}

Ensuite, nous devons ajouter les chaînes rejetées dans le fichier de configuration de WP Super Cache, situé dans wp-content / wp-cache-config.php, en mettant à jour la valeur de l'entrée $ cache_rejected_uri avec notre liste de chemins:

 fonction set_rejected_strings_in_wp_super_cache () {

  if ($ denied_strings = get_rejected_strings ()) {

    // conserve les valeurs d'origine dans
    $ excluded_strings = array_merge (
      tableau ('wp -. * \\. php', 'index \\. php'),
      $ rejetée_strings
    )
      
    global $ wp_cache_config_file;
    $ cache_rejected_uri = "array ('". implode ("', '", $ rejeté_strings). "')";
    wp_cache_replace_line ('^ *  $ cache_rejected_uri', " $ cache_rejected_uri =". $ cache_rejected_uri. ";", $ wp_cache_config_file);
  }
}

Lors de l'exécution de la fonction set_rejected_strings_in_wp_super_cache les paramètres sont mis à jour avec les nouvelles chaînes rejetées:


 Les paramètres WP Super Cache permettent de désactiver la mise en cache des chaînes sur liste noire
. Blacklisting les chemins d'accès à partir de l'état d'accès des utilisateurs WP Super Cache. ( Grand aperçu )

Enfin, comme nous sommes maintenant en mesure de désactiver la mise en cache pour les pages spécifiques nécessitant un état utilisateur, il n'est plus nécessaire de désactiver la mise en cache pour les utilisateurs connectés:


 Mise en cache désactivée pour les utilisateurs connus dans WP Super Cache
Plus besoin de désactiver la mise en cache pour les utilisateurs connectés! ( Grand aperçu )

Conclusion

Dans cet article, nous avons exploré un moyen d'améliorer la mise en cache de notre site, principalement pour permettre la mise en cache sur le site même lorsque les utilisateurs sont connectés. La stratégie repose sur la désactivation de la mise en cache uniquement pour les pages nécessitant un état utilisateur, et sur l'utilisation de composants pouvant décider de s'afficher ou non sur le client ou sur le côté serveur, en fonction de la page accédant ou non à l'état utilisateur.

De manière générale, la stratégie peut être implémenté sur toute architecture prenant en charge le rendu des composants côté serveur. En particulier, nous avons analysé son implémentation pour les sites WordPress via Gutenberg, en indiquant si cela valait la peine de maintenir deux bases de code, une en PHP pour le code côté serveur et une en JavaScript pour le code côté client. .

Enfin, nous avons expliqué que la solution pouvait être intégrée au plug-in de mise en cache via un script personnalisé pour générer automatiquement la liste des pages afin d'éviter la mise en cache, ainsi que le code correspondant au plug-in WP Super Cache.

Après la mise en œuvre de cette stratégie sur mon site, peu importe que les visiteurs soient connectés ou non. Ils accéderont toujours à une version en cache de la page d'accueil, offrant une réponse plus rapide et une meilleure expérience utilisateur.

 Smashing Editorial (rb, ra, yk, il)




Source link