Affichage dynamique avec Rendertron

Jeudi 31 janvier 2019

De nombreux frameworks d'interface utilisent JavaScript pour afficher des contenus. Ainsi, Google peut mettre un certain temps à indexer vos contenus ou à mettre à jour les contenus déjà indexés.

L'affichage dynamique est une solution de contournement évoquée lors de la conférence Google I/O de cette année. Il existe plusieurs façons de le mettre en œuvre. Nous allons voir dans cet article de blog un exemple d'affichage dynamique avec Rendertron, une solution Open Source basée sur Chromium headless.

Quels sont les sites qui devraient utiliser l'affichage dynamique ?

Tous les moteurs de recherche et les robots de réseaux sociaux qui explorent votre page ne sont pas capables d'exécuter JavaScript. Ainsi, Googlebot peut mettre un certain temps à exécuter vos fichiers JavaScript et présente certaines limites.

L'affichage dynamique est utile pour les contenus fréquemment modifiés et dont l'affichage requiert JavaScript. Vous pouvez améliorer l'expérience des utilisateurs sur votre site (en particulier le délai d'affichage du first meaningful paint) avec un rendu hybride (Angular Universal, par exemple).

Comment l'affichage dynamique fonctionne-t-il ?

Fonctionnement de l'affichage dynamique

L'affichage dynamique consiste à basculer entre un contenu affiché côté client et un contenu préaffiché pour des user-agents spécifiques.

Vous aurez besoin d'un moteur de rendu pour exécuter le code JavaScript et produire du code HTML statique. Rendertron est un projet Open Source qui utilise Headless Chromium pour effectuer le rendu. Les applications ayant une seule page chargent souvent des données en arrière-plan ou reportent les tâches d'affichage du contenu. Rendertron est doté de mécanismes qui déterminent quand l'affichage du contenu d'un site Web est terminé. Il attend que l'ensemble des demandes réseau et des tâches soient terminées.

Dans cet article, nous allons :

  1. Passer en revue un exemple d'application Web
  2. Configurer un petit serveur express.js pour diffuser l'application Web
  3. Installer et configurer Rendertron en tant que middleware pour l'affichage dynamique

Exemple d'application Web

L'application Web "kitten corner" utilise JavaScript pour charger des images de chats à partir d'une API et les afficher sous forme de grille.

Des images de chats mignons et un bouton pour en afficher d'autres, que demander de plus à cette application Web !

Voici son code JavaScript :

const apiUrl = 'https://api.thecatapi.com/v1/images/search?limit=50';
   const tpl = document.querySelector('template').content;
   const container = document.querySelector('ul');
   function init () {
     fetch(apiUrl)
     .then(response => response.json())
     .then(cats => {
       container.innerHTML = '';
       cats
         .map(cat => { const li = document.importNode(tpl, true); li.querySelector('img').src = cat.url; return li;
         }).forEach(li => container.appendChild(li));
     })
   }
   init();
   document.querySelector('button').addEventListener('click', init);

L'application Web utilise du JavaScript moderne (ES6), qui n'est pas encore compatible avec Googlebot. Nous pouvons utiliser le test d'optimisation mobile pour vérifier si Googlebot peut lire les contenus :

Si l'on en croit le test d'optimisation mobile, la page est optimisée pour le mobile, mais on ne voit pas les images de chats sur la capture d'écran. L'en-tête et le bouton s'affichent, mais pas les photos de chats.

Même si ce problème se résout facilement, c'est un bon exercice pour s'entraîner à configurer l'affichage dynamique. Grâce à celui-ci, Googlebot pourra voir les photos de chats sans que vous ayez à modifier le code de l'application Web.

Configurer le serveur

Pour diffuser l'application Web, nous allons utiliser express, une bibliothèque node.js afin de créer des serveurs Web.

Voici le code du serveur (vous trouverez le code source du projet complet ici) :

const express = require('express');
const app = express();
const DIST_FOLDER = process.cwd() + '/docs';
const PORT = process.env.PORT || 8080;
// Serve static assets (images, css, etc.)
app.get('*.*', express.static(DIST_FOLDER));
// Point all other URLs to index.html for our single page app
app.get('*', (req, res) => {
  res.sendFile(DIST_FOLDER + '/index.html');
});
// Start Express Server
app.listen(PORT, () => {
  console.log(`Node Express server listening on https://localhost:${PORT} from ${DIST_FOLDER}`);
});

La version en ligne se trouve ici. Si vous utilisez un navigateur récent, vous devriez voir des images de chats. Pour exécuter le projet à partir de votre ordinateur, vous avez besoin de node.js afin d'exécuter les commandes suivantes :

npm install --save express rendertron-middleware
node server.js

Dirigez ensuite votre navigateur vers https://localhost:8080. Vous devez maintenant configurer l'affichage dynamique.

Déployer une instance Rendertron

Rendertron exécute un serveur qui renvoie du code HTML statique pour une URL donnée en utilisant Chromium headless. Nous allons suivre la recommandation du projet Rendertron et utiliser Google Cloud Platform.

Le formulaire pour créer un projet Google Cloud Platform.

Vous pouvez commencer à utiliser le niveau d'utilisation disponible sans paiement. L'utilisation de cette configuration en production peut entraîner des coûts, conformément aux tarifs de Google Cloud Platform.

  1. Créez un projet dans la console Google Cloud. Notez l'ID du projet situé sous le champ de saisie.
  2. Installez Google Cloud SDK comme décrit dans la documentation, puis connectez-vous.
  3. Clonez le dépôt Rendertron depuis GitHub avec :
    git clone https://github.com/GoogleChrome/rendertron.git
    cd rendertron
  4. Exécutez les commandes suivantes pour installer des dépendances et compiler Rendertron sur votre ordinateur :
    npm install && npm run build
  5. Activez le cache de Rendertron en créant un fichier nommé config.json dans le répertoire de Rendertron avec le contenu suivant :
    { "datastoreCache": true }
  6. Exécutez la commande suivante depuis le répertoire de Rendertron. Remplacez YOUR_PROJECT_ID par l'ID de votre projet obtenu à l'étape 1.
    gcloud app deploy app.yaml --project YOUR_PROJECT_ID
  7. Sélectionnez la région de votre choix et confirmez le déploiement. Attendez la fin du déploiement.
  8. Saisissez l'URL YOUR_PROJECT_ID.appspot.com. L'interface de Rendertron devrait s'afficher avec un champ de saisie et quelques boutons.
Interface utilisateur de Rendertron après le déploiement sur Google Cloud Platform

Lorsque l'interface Web de Rendertron s'affiche, cela signifie que vous avez déployé votre propre instance Rendertron. Notez l'URL de votre projet (YOUR_PROJECT_ID.appspot.com), car vous en aurez besoin à la prochaine étape du processus.

Ajouter Rendertron au serveur

Le serveur Web utilise express.js et Rendertron possède un middleware express.js. Exécutez la commande suivante dans le répertoire du fichier server.js :

npm install --save rendertron-middleware

Cette commande installe l'intergiciel rendertron-middleware depuis npm pour que nous puissions l'ajouter au serveur :

const express = require('express');
const app = express();
const rendertron = require('rendertron-middleware');

Configurer la liste de robots

Rendertron utilise l'en-tête HTTP user-agent pour déterminer si une requête provient d'un bot ou du navigateur d'un utilisateur. Il compare ces requêtes à une liste complète d'user-agents de robots. Par défaut, cette liste n'inclut pas Googlebot, car il peut exécuter JavaScript. Pour que Rendertron affiche également les requêtes Googlebot, ajoutez Googlebot à liste des user-agents :

const BOTS = rendertron.botUserAgents.concat('googlebot');
const BOT_UA_PATTERN = new RegExp(BOTS.join('|'), 'i');

Rendertron compare l'en-tête user-agent à cette expression régulière ultérieurement.

Ajouter le middleware

Pour envoyer des requêtes de bot à l'instance Rendertron, nous devons ajouter le middleware à notre serveur express.js. Le middleware vérifie l'user-agent à l'origine de la requête et envoie les requêtes des robots reconnus à l'instance Rendertron. Ajoutez le code suivant à server.js et n'oubliez pas de remplacer YOUR_PROJECT_ID par votre ID de projet Google Cloud Platform :

app.use(rendertron.makeMiddleware({
  proxyUrl: 'https://YOUR_PROJECT_ID.appspot.com/render',
  userAgentPattern: BOT_UA_PATTERN
}));

Les robots qui demandent l'exemple de site Web reçoivent le code HTML de Rendertron et n'ont donc pas besoin d'exécuter JavaScript pour afficher le contenu.

Tester la configuration

Pour vérifier la bonne configuration de Rendertron, exécutez à nouveau le test d'optimisation mobile.

Le test d'optimisation mobile indique que la page est adaptée aux mobiles et que tous les chats disparus sont dans la capture d'écran.

Cette fois-ci, les photos de chats sont visibles. Dans l'onglet "HTML", nous pouvons voir tout le HTML généré par le code JavaScript. On voit également que grâce à Rendertron, le contenu n'a plus besoin de JavaScript pour s'afficher.

Conclusion

Vous avez créé une configuration d'affichage dynamique sans modifier l'application Web. Grâce à ces modifications, vous pouvez proposer une version HTML statique de l'application Web aux robots d'exploration.