Maison  >  Article  >  développement back-end  >  Optimisation web avec ETags. Exemple avec WordPress

Optimisation web avec ETags. Exemple avec WordPress

WBOY
WBOYoriginal
2024-09-09 16:30:41562parcourir

Optimisation Web avec ETags. Exemple avec WordPress

Cet article a été initialement publié en 2014 en 2019 dans Web Optimization with ETags. Exemple avec WordPress

Optimización web con ETags. Ejemplo con WordPress

Je n'ai pas écrit sur l'optimisation depuis un moment. Vous savez déjà ce que vous me connaissez, pourquoi c'était dû. Cependant, je ne peux pas laisser les soi-disant colporteurs du WPO m'empêcher d'écrire sur quelque chose que j'aime. Alors voilà, vous avez un nouveau post.

Je suis sûr que ça vous est arrivé. Vous arrivez un jour sur votre lieu de travail, allumez votre ordinateur, ouvrez votre email et après y avoir jeté un œil, vous ouvrez un terminal et tapez : git pull. La réponse du terminal n'attend pas : Déjà à jour..

Avez-vous déjà pensé à ce qui se passe derrière ce git pull ? Je fais. En supposant, je dirais qu'en faisant un git pull, vous envoyez de manière transparente au serveur la date de la dernière modification que vous avez. Le référentiel vérifie la date de la dernière modification que vous lui envoyez par rapport à la date de la dernière modification dont il dispose, de sorte que :

  • Si votre rendez-vous est plus ancien, il vous envoie tous les push/modifications qui ont été effectués depuis. Il vous enverra également ces modifications, à la date à laquelle elles ont été apportées. Ainsi, si vous réécriviez git pull, vous enverriez la date du dernier de ces changements et tout recommencerait.
  • Si votre date correspond à la date du référentiel pour la dernière modification, il vous indiquera que tout est à jour.

Cette procédure, qui pour moi était la plus logique, n'est pas la vraie. Le vrai est similaire, mais pas exact. Chaque fois qu'une poussée est effectuée. Le référentiel associe un jeton (code d'identification alphanumérique, quelque chose comme ae3d9735f280381d0d97d3cdb26066eb16f765a5) au dernier commit. Lorsque vous effectuez un git pull, le dernier jeton que vous possédez est comparé à la liste des jetons dont il dispose. Si votre token est ancien, il vous envoie les modifications depuis lors avec leurs tokens correspondants. Si le jeton était le dernier, il vous dira que vous êtes à jour.

À ce stade, vous me direz : Manuel, mais cet article ne concernait-il pas l'optimisation des sites Web avec WordPress ? Certainement, et c’est toujours le cas. Tant le premier cas présenté (celui de la date), que le second (celui du token) sont des modes de fonctionnement du protocole HTTP. Voyons ça.

Dernière modification

Imaginez que votre navigateur envoie une requête à mon serveur pour télécharger le favicon de mon site internet. Dans la réponse de mon serveur à votre navigateur, il y aura la chaîne (ou en-tête HTTP) : Last-Modified : Thu, 29 Dec 2016 11:55:29 GMT. Grâce à lui, mon serveur informe votre navigateur de la dernière modification du favicon. Ainsi le navigateur, une fois l'image téléchargée, la sauvegardera dans son cache avec les métadonnées « Last-Modified » et la valeur Jeu 29 décembre 2016 11:55:29 GMT

Si après quelques secondes, quelques jours ou quelques mois, vous décidez de revenir sur mon site, votre navigateur aura à nouveau besoin du favicon de mon site. Cependant, n'oubliez pas qu'il dispose également d'une copie de l'image dans son cache. Comment savoir si votre favicon en cache est la dernière ou si vous devez la télécharger à nouveau ? Simple, faire un « git pull ». Autrement dit, le navigateur envoie à nouveau une demande de favicon à mon serveur, mais l'informant qu'il dispose d'une version de l'image à partir d'une certaine date. Il y a deux réponses possibles depuis mon serveur :

  • Le favicon qui est maintenant utilisé sur mon site Web est plus récent, donc mon serveur enverra la nouvelle image à votre navigateur, ainsi que la nouvelle date de dernière modification de cette nouvelle image.
  • Le favicon qui est désormais utilisé sur mon site web est le même que la date indiquée par votre navigateur. Autrement dit, l'image du serveur et l'image du cache du navigateur sont identiques. Mon serveur indique alors à votre navigateur que l'image n'a pas été modifiée (avec le code HTTP 304 Not Modified). Votre navigateur utilise ensuite l'image du cache et vous évite d'avoir à télécharger à nouveau l'image (économisant ainsi de nombreux octets de votre débit de données).

Etags

Si vous vous souvenez, au début du post, je vous ai dit que Git travaillait avec des jetons pour déterminer quand les modifications étaient apportées. HTTP, en plus de la date de dernière modification, permet de travailler avec des tokens appelés ETags (Entity Tags). Un ETag est un code alphanumérique (tel que 5864f9b1-47e) sans format par défaut (c'est-à-dire que la norme HTTP ne précise pas, ou presque, quel format doit avoir le jeton). C'est le propriétaire d'un site qui détermine quel sera son format.

Par défaut, les serveurs web comme Apache créent l'ETag de chaque fichier en fonction de sa date de modification (et parfois aussi de la taille du fichier). Ceci est redondant (l'en-tête HTTP de date de dernière modification est basé sur les mêmes critères) et sous-optimal (car il ajoute plus d'informations aux requêtes qui ne sont d'aucune utilité). Il est conseillé dans ce cas de configurer votre serveur web pour qu'il n'utilise pas d'ETags avec les fichiers. Par exemple, pour désactiver les fichiers ETags (ou FileETags) pour Apache, ajoutez le code suivant à tú.htacess : FileETag None

Je suis sûr que vous vous demandez si le dialogue entre navigateur/serveur utilisant un ETag est le même que ce que nous avons vu pour la dernière date de modification et si l'utilisation des deux formulaires n'est pas optimale et redondante. Pourquoi utiliser les ETags ?

La date de modification est suffisante pour les requêtes HTTP vers des fichiers, mais avec les requêtes HTTP vers des pages Web (HTML), elle est insuffisante. Une page Web dépend de nombreux facteurs/éléments interdépendants (contenu, commentaires, structure HTML, ...) et non d'un seul fichier. Il serait donc très difficile de trouver une date de dernière modification unifiée pour tous ces éléments. Je sais que ce que je dis est compliqué à suivre, je vais essayer de l'expliquer autrement :

Imaginez que j'attribue comme date de modification de la page web (HTTML) de cette entrée, la date de modification du texte de l'entrée. Votre navigateur lors de la saisie mettrait en cache cette page ainsi que la date de dernière modification de la publication. Si vous saisissez à nouveau une minute plus tard, la publication n'ayant pas changé (et donc sa date de modification), votre navigateur utilisera à nouveau la version qu'il a en cache. Si quelqu'un m'écrivait un commentaire et que vous reveniez, vous ne verriez pas le commentaire. Eh bien, le texte du message n'a pas changé, donc la date de la dernière modification n'a pas changé non plus, donc votre navigateur vous montrera à nouveau la version de son cache. La même chose se produirait si je modifiais le HTML et ajoutais un nouveau CSS. Le contenu de la publication n'a pas changé, la date non plus et votre navigateur continuera d'afficher la version cache.

Si au lieu de travailler avec les dates de dernière modification de la publication, nous attribuons à la page Web de la publication un ETag au format suivant : {fecha_modificacion_contenido_post}_{date_last_commentario_post}_{number_version_del_tema_WP}

Lorsque votre navigateur entre dans la publication pour la première fois, il mettra en cache la page Web (HTML) avec son ETag associé en tant que métadonnées. Si vous modifiez l'un des critères du jeton (date de publication, date du dernier commentaire ou version actuelle du thème WP), l'ETag associé à la page Web sera différent. Donc, si vous saisissez à nouveau le message, mon serveur vous informera que l'ETag de votre navigateur n'est pas le plus récent et vous enverra à nouveau la page Web entière, ainsi que le nouvel ETag.

Si rien n'avait changé, le token/ETag serait le même (à la fois dans le navigateur et sur le serveur), donc lorsque vous visiterez la page avec votre navigateur, mon serveur vous enverrait un 304 vous informant que rien n'a changé. modifié (en termes WPO, on dit qu'il est encore frais) et utilisez donc la version de votre cache.

Avantage Etags

Ce que je n'ai pas mentionné jusqu'à présent, ce sont les avantages des ETags. En voici quelques-uns :

  • Moins de données transférées entre serveur/navigateur. Cela signifie sauvegarder les données de l'utilisateur afin que votre site Web ne coûte pas trop cher à vos utilisateurs et également au serveur (important si vous avez souscrit un hébergement basé sur le paiement de la quantité de données transférées).
  • Le serveur n'a plus besoin de générer le HTML, avec tout ce que cela implique : économiser de la mémoire et du CPU et libérer la base de données de travail.
  • Chargement beaucoup plus rapide de votre site Web, améliorant ainsi l'expérience utilisateur.

Plugin WordPress

Tout ce que nous avons vu est à un niveau élevé, nous allons voir un petit plugin qui utilise ETag pour les pages/posts WordPress.

# etags.php
<?php

namespace trasweb\webperf\ETags;

/*
 * Plugin Name:       ETags en posts
 * Plugin URI:        https://trasweb.net/webperf/optimizacion-web-con-etags
 * Description:       Usa el cache en navegador para tus posts.
 * Version:           0.0.1
 * Author:            Manuel Canga / Trasweb
 * Author URI:        https://trasweb.net
 * License:           GPL
 */

add_action('wp', function () {
    if (is_admin() || ! is_singular()) {
        return;
    }

    $etag_from_navigator = $_SERVER[ 'HTTP_IF_NONE_MATCH' ]??'';
    $current_ETag        = get_current_ETag();

    if ($etag_from_navigator === $current_ETag) {
        status_header(304);
        exit;
    }

    header('ETag: ' . $current_ETag);
});

function get_current_ETag()
{
    $last_modified_time_of_content = (int)get_post_time();
    $date_of_last_comment          = get_date_of_last_comment();
    $theme_version                 = wp_get_theme()[ "Version" ]??'0.0.0';

    return md5("{$last_modified_time_of_content}_{$date_of_last_comment}_{$theme_version}");
}

function get_date_of_last_comment()
{
    $query = [
        'post_id' => get_the_ID() ?: 0,
        'orderby' => ['comment_date_gmt'],
        'status'  => 'approve',
        'order'   => 'DESC',
        'number'  => 1,
    ];

    $last_comment = get_comments($query)[ 0 ]??null;

    return $last_comment->comment_date_gmt??0;
}

Tout d’abord, disons que ce plugin n’est qu’une formation. Comme pour toute technique d'optimisation web, comme la minification/unification des ressources CSS/JS ou l'utilisation du cache serveur, une étude du site s'impose au préalable.

Comme vous pouvez le constater, cela ne pourrait pas être plus simple. Dans un premier temps, l'ETag du navigateur est obtenu s'il existe (ligne 20). Deuxièmement, l'Etag associé à la publication/page actuelle est obtenu (ligne 21).

Si les deux sont identiques, un code 304 est envoyé au navigateur (ligne 24, c'est le cas montré dans l'image principale de ce post) et l'exécution se termine. Le navigateur recevra le code 304 et saura qu'il doit utiliser la version de la page dans son cache.

Si les Etags sont différents (soit parce que le navigateur entre pour la première fois, soit parce que le token a changé), l'ETag est envoyé au navigateur et WP est autorisé à poursuivre son cours (qui envoie le contenu du post en cours /page ).

L'Etag est généré dans la fonction get_current_ETag (ligne 31 à 38) en fonction de la dernière fois que la publication/la page a été modifiée, de la date du dernier commentaire sur la publication et de la version du sujet actuel. Si l'un de ces paramètres change, le jeton changera, obligeant le navigateur à télécharger la nouvelle version du site Web.

C'est tout. J'espère que vous l'avez aimé et que cela vous aidera à rendre votre site Web plus rapide.


Veuillez le partager

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn