Rendering dinamico con Rendertron

Giovedì 31 gennaio 2019

Molti framework frontend si affidano a JavaScript per mostrare i contenuti e ciò significa che Google potrebbe impiegare del tempo per indicizzare i vostri contenuti o aggiornare quelli indicizzati.

Una soluzione alternativa di cui abbiamo parlato durante la conferenza Google I/O di quest'anno è il rendering dinamico. Esistono molti modi per implementarlo. Questo post del blog mostra un'implementazione di esempio del rendering dinamico utilizzando Rendertron, una soluzione open source basata su Chromium headless.

Per quali siti vale la pena prendere in considerazione il rendering dinamico?

Non tutti i motori di ricerca o i bot di social media che visitano il vostro sito web possono eseguire JavaScript. Googlebot potrebbe richiedere tempo per eseguire JavaScript e presenta anche alcune limitazioni.

Il rendering dinamico è utile per i contenuti che cambiano spesso e richiedono JavaScript per la visualizzazione. L'esperienza utente sul vostro sito, in particolare il tempo relativo alla metrica First Meaningful Paint potrebbe beneficiare dell'utilizzo del rendering ibrido, ad esempio Angular Universal.

Come funziona il rendering dinamico?

Come funziona il rendering dinamico

Eseguire il rendering dinamico significa passare da contenuti con rendering lato client a contenuti di cui viene eseguito il pre-rendering per specifici user agent.

Per eseguire il codice JavaScript e generare l'HTML statico avrete bisogno di un renderer. Rendertron è un progetto open source che utilizza Chromium headless per il rendering; le app a pagina singola spesso caricano i dati in background o rimandano il lavoro per visualizzare i loro contenuti. Rendertron dispone di meccanismi che consentono di determinare quando viene completato il rendering di un sito web; attende che tutte le richieste di rete siano terminate e che non ci sia alcun lavoro in sospeso.

Questo post tratta dei seguenti argomenti:

  1. Esame di un'app web di esempio
  2. Configurazione di un piccolo server express.js per pubblicare l'applicazione web
  3. Installazione e configurazione di Rendertron come middleware per il rendering dinamico

App web di esempio

L'app web "Kitten Corner" utilizza JavaScript per caricare una serie di immagini di gatti da un'API e le mostra in una griglia.

Immagini di gatti teneri in una griglia e un pulsante per mostrarne altre: a questa applicazione web non manca davvero nulla!

Ecco il codice 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'app web utilizza JavaScript moderno (ES6), che non è ancora supportato in Googlebot. Possiamo utilizzare il test di ottimizzazione mobile per verificare se Googlebot riesce a rilevare i contenuti:

Il test di ottimizzazione mobile mostra che la pagina è ottimizzata per il mobile, ma nello screenshot mancano tutti i gatti. Il titolo e il pulsante vengono visualizzati, ma non ci sono le immagini dei gatti.

Anche se questo problema è semplice da risolvere, è un buon esercizio per imparare a configurare il rendering dinamico, che consentirà a Googlebot di vedere le immagini dei gatti senza modifiche al codice dell'app web.

Configurare il server

Per gestire l'applicazione web, utilizziamo express, una libreria node.js, per creare i server web.

Il codice del server ha il seguente aspetto (il codice sorgente del progetto completo è disponibile qui):

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}`);
});

Potete provare l'esempio online: dovreste vedere una serie di immagini di gatti, se usate un browser moderno. Per eseguire il progetto dal computer, vi serve node.js per eseguire questi comandi:

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

Quindi, indirizzate il browser a https://localhost:8080. A questo punto potete configurare il rendering dinamico.

Eseguire il deployment di un'istanza Rendertron

Rendertron esegue un server che accetta un URL e restituisce un codice HTML statico per l'URL utilizzando Chromium headless. Seguiremo il consiglio del progetto Rendertron e utilizzeremo la piattaforma Google Cloud.

Il modulo per creare un nuovo progetto della piattaforma Google Cloud.

Tenete presente che potete iniziare con il livello di utilizzo disponibile senza costi; l'uso di questa configurazione in produzione può comportare costi in base ai prezzi della piattaforma Google Cloud.

  1. Create un nuovo progetto in Google Cloud Console. Prendete nota di "ID progetto" sotto il campo di immissione.
  2. Installate Google Cloud SDK come descritto nella documentazione ed eseguite l'accesso.
  3. Clonate il repository Rendertron da GitHub con:
    git clone https://github.com/GoogleChrome/rendertron.git
    cd rendertron
  4. Eseguite i comandi seguenti per installare le dipendenze e creare Rendertron sul vostro computer:
    npm install && npm run build
  5. Attivate la cache di Rendertron creando un nuovo file denominato config.json nella directory rendertron con i seguenti contenuti:
    { "datastoreCache": true }
  6. Eseguite il comando seguente dalla directory rendertron. Sostituite YOUR_PROJECT_ID con il vostro ID progetto del passaggio 1.
    gcloud app deploy app.yaml --project YOUR_PROJECT_ID
  7. Selezionate un'area geografica di vostra scelta e confermate il deployment. Attendete il completamento del processo.
  8. Inserite l'URL YOUR_PROJECT_ID.appspot.com. Dovreste visualizzare l'interfaccia di Rendertron con un campo di immissione e alcuni pulsanti.
UI di Rendertron dopo il deployment nella piattaforma Google Cloud

Se vedete l'interfaccia web di Rendertron, significa che avete eseguito il deployment della vostra istanza di Rendertron. Prendete nota dell'URL del vostro progetto (YOUR_PROJECT_ID.appspot.com) perché vi servirà nella parte successiva della procedura.

Aggiungere Rendertron al server

Il server web utilizza express.js e Rendertron ha un middleware express.js. Eseguite questo comando nella directory del file server.js:

npm install --save rendertron-middleware

Questo comando installa il middleware Rendertron da npm in modo da poterlo aggiungere al server:

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

Configurare l'elenco dei bot

Rendertron utilizza l'intestazione HTTP user-agent per determinare se una richiesta proviene da un bot o dal browser di un utente. Include un elenco aggiornato di user agent bot con cui eseguire il confronto. Per impostazione predefinita, questo elenco non include Googlebot, perché Googlebot può eseguire JavaScript. Per fare in modo che Rendertron esegua il rendering delle richieste di Googlebot, aggiungi Googlebot all'elenco di user agent:

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

Rendertron confronta l'intestazione user-agent con questa espressione regolare in un secondo momento.

Aggiungere il middleware

Per inviare le richieste dei bot all'istanza di Rendertron, dobbiamo aggiungere il middleware al nostro server express.js. Il middleware controlla lo user agent richiedente e inoltra le richieste dai bot noti all'istanza di Rendertron. Aggiungete il seguente codice a server.js e non dimenticate di sostituire YOUR_PROJECT_ID con il vostro ID progetto della piattaforma Google Cloud:

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

I bot che richiedono il sito web di esempio ricevono l'HTML statico da Rendertron, quindi non è necessario che i bot eseguino JavaScript per visualizzare i contenuti.

Verifica della nostra configurazione

Per verificare se la configurazione di Rendertron è riuscita, ripetete il test di ottimizzazione mobile.

Il test di ottimizzazione mobile mostra che la pagina è ottimizzata per il mobile e lo screenshot ora include tutti i gatti mancanti.

A differenza del primo test, le immagini dei gatti sono visibili. Nella scheda HTML possiamo vedere tutto il codice HTML generato da JavaScript e che Rendertron ha eliminato la necessità di JavaScript per la visualizzazione dei contenuti.

Conclusione

Avete creato una configurazione di rendering dinamico senza apportare modifiche all'app web. Con queste modifiche, potete fornire ai crawler una versione HTML statica dell'app web.