SEO per JavaScript: guida, sperimentazione, principi

Oltre a condividere risorse utili relative alla SEO per JavaScript, vedremo un test per capire come si comportano i motori di ricerca (Google, Bing e Yandex) quando si trovano a dover scansionare ed indicizzare pagine renderizzate attraverso JS. Infine alcune considerazioni per SEO e sviluppatori.

SEO per JavaScript: un esperimento per chiarire l'argomento
SEO per JavaScript: un esperimento per chiarire l'argomento

JavaScript è senza dubbio uno dei protagonisti del web odierno, e come dice ogni tanto John Mueller, "non se ne andrà facilmente".

Spesso si tratta di un argomento "demonizzato" dalla community SEO, ma credo che questo dipenda dalla mancanza di approfondimento tecnico sullo sviluppo in JavaScript e sul rendering delle pagine web. Ma anche dalla difficoltà di comunicazione di tali concetti con i team di sviluppo.

Questo post si divide in due parti: la prima (breve) offre alcune risorse per approfondire la tematica; nella seconda (più approfondita) vediamo un semplicissimo test che mette alla prova i motori di ricerca su una pagina che prende vita quasi totalmente da JavaScript.

Nel seguente video, che deriva dal Search Marketing Connect 2022, racconto gli aspetti più importanti che i SEO devono considerare quando devono gestire progetti con componenti JavaScript.

SEO per JavaScript: un manuale con i concetti principali da considerare


Alcune risorse che introducono la SEO per JavaScript

Nel seguente video Martin Splitt, facendo chiaramente riferimento a Google, introduce l'argomento, spiegando l'importanza di ragionare in ottica SEO su progetti sviluppati in JavaScript, ovvero per le pagine che renderizzano contenuti critici in JS o per le cosiddette single-page apps.

JavaScript e SEO: le basi

Se vuoi che le tue risorse vengano indicizzate prima possibile, assicurati che il contenuto più importante sia nel sorgente della pagina (renderizzato lato server).

Perché questo? Perché dobbiamo sempre tener presente lo schema che segue, ovvero le due ondate di indicizzazione.

Il flusso di scansione, indicizzazione, rendering e riconsiderazione, e le due ondate di elaborazione
Il flusso di scansione, indicizzazione, rendering e riconsiderazione, e le due ondate di elaborazione

Il contenuto generato da JavaScript viene considerato nella seconda ondata di indicizzazione, perché deve attendere la fase di rendering.

Nel video che segue, invece, vengono dati dei suggerimenti di base per la SEO su progetti sviluppati in JavaScript.

Martin Splitt: i principali consigli relativi alla SEO in ambiente Javascript

Come ultima risorsa, consiglio la lettura (e la visualizzazione del video) del seguente post, in cui approfondisco le diverse tipologie di rendering e i framework JS.

SMXL 2021: un intervento dedicato alla Page Experience
Sul palco virtuale di SMXL Milan ho portato alcune innovazione tecnologiche volte a migliorare le performance dei siti web, e quindi i Core Web Vitals e la Page Experience. In particolare ho parlato di rendering delle pagine, di Early Hints, di Signed Exchanges (SXGs), di Priority Hints e di HTTP/3.
Siamo diretti verso UX straordinarie, ma siamo diretti anche verso la necessità di competenze tecniche sempre maggiori.

Un semplice test per chiarire come i motori di ricerca trattano JavaScript

Descriverò un test messo in azione proprio per ripercorrere le fasi descritte dalla documentazione di Google (scansione > indicizzazione > rendering > riconsiderazione), ma che si estende anche oltre al motore di ricerca di Mountain View.

Si tratta di un test abbastanza "estremo" in termini di soluzione tecnica applicata, realizzato usando semplici funzioni JavaScript, senza l'utilizzo di framework particolari. Lo scopo è esclusivamente comprendere le dinamiche che mette in atto il motore di ricerca, non un esercizio di stile.

1) La pagina web

Per prima cosa ho creato una pagina web avente le seguenti caratteristiche.

  • Una pagina HTML contenente i principali TAG strutturali, senza alcun testo, ad eccezione del contenuto del tag <title>, un sottotitolo in un tag <h4> e una stringa nel footer.
  • Questi contenuti presenti nell'HTML sorgente hanno uno scopo preciso: dare ai motori di ricerca dei dati immediatamente alla prima elaborazione.
  • Una funzione JavaScript, una volta che il DOM (Document Object Model) è completo, si occupa di renderizzare tutti i contenuti (un post completo generato utilizzando GPT-3).
$(document).ready( function () {
  hydration();
});
  • I contenuti renderizzati dalla funzione non sono presenti nella pagina in stringhe JavaScript o JSON, ma vengono ottenuti attraverso chiamate remote (AJAX).
  • Anche i dati strutturati vengono "iniettati" via JavaScript ottenendo la stringa JSON attraverso una chiamata remota.
  • Ho appositamente fatto in modo che la funzione JavaScript sovrascrivesse il contenuto del tag <title>, generasse il contenuto del tag <h1> e creasse la description. Il motivo è che questo avrebbe stravolto completamente lo snippet in SERP in caso fossero stati considerati i dati renderizzati da JS.
  • Una delle due immagini che vengono renderizzate via JS, è stata indicata nell'header della pagina in un tag <link> (rel="preload") per dare un riferimento e capire se questo può velocizzare l'indicizzazione della risorsa.
La struttura della pagina web per il test
La struttura della pagina web per il test

2) Segnalazione ai motori di ricerca e test

Dopo aver pubblicato la pagina, l'ho segnalata ai motori di ricerca, ed in particolare a Google (attraverso il "controllo URL" di Search Console), a Bing (attraverso "Invio URL" di Webmaster Tool) e a Yandex (attraverso "Reindex pages" di Webmaster Tool).

In questa fase, ho eseguito alcuni test.

  • Il tool di Merkle "Fetch & Render" che solitamente utilizzo per fare test di rendering, ha generato la pagina correttamente. Lo strumento simula Googlebot usando Chromium 79 headless.
    Una curiosità: tra i tool di Merkle è presente anche un Pre-rendering Tester, il quale consente di verificare la risposta HTML in base allo user-agent che effettua la richiesta.
Fetch & Render di Merkle: tool per i test di rendering
Fetch & Render di Merkle: tool per i test di rendering
  • Il Test dei risultati avanzati di Google, ha generato correttamente il DOM e lo screenshot della pagina. Il tool ha rilevato correttamente anche i dati strutturati, individuando l'entità di tipo "Articolo".
Il DOM generato dal Test dei risultati avanzati di Google
Il DOM generato dal Test dei risultati avanzati di Google
  • Il tool di Search Console (controllo URL), inizialmente, ha alternato momenti in cui i contenuti sono stati generati con successo, a momenti in cui il rendering non è stato perfetto, ma credo sia dipeso dal tempo di esecuzione.

3) Indicizzazione

In questa fase, tutti i motori di ricerca si sono comportati allo stesso modo: dopo alcune ore, il risultato era presente in tutte le SERP.

Gli snippet, come si vede dalle immagini, sono composti dal contenuto del tag <title> e da una descrizione ricavata dai dati presenti del main content anche senza l'intervento di JavaScript.

Nessuna immagine presente nella pagina è stata indicizzata.

4) Modifica, sitemap e API indexing di Google

Il giorno successivo, gli snippet erano identici. Ho fatto alcune azioni per mandare dei segnali ai motori di ricerca.

  • Ho modificato l'HTML della pagina, aggiungendo la favicon, il nome dell'autore (fittizio) del post e la data di pubblicazione. L'obiettivo era capire se i motori avrebbero aggiornato lo snippet prima di una potenziale analisi del renderizzato.
  • Contestualmente ho aggiornato il JSON dei dati strutturati aggiornando la data di modifica ("dateModified").
  • Ho inviato la sitemap contenente l'URL della nuova pagina ai tool per i webmaster dei diversi motori di ricerca.
  • Ho segnalato ai motori di ricerca che la pagina è stata modificata, ed in particolare, per Google, attraverso l'API indexing.

I risultati

Cos'è successo dopo qualche giorno?

Google ha eseguito il rendering e rielaborato lo snippet
Google ha eseguito il rendering e rielaborato lo snippet

1) Google, come da documentazione, ha eseguito il rendering processando il JavaScript, quindi ha rielaborato il risultato in SERP utilizzando correttamente i contenuti.

2) Anche la prima immagine del post è stata indicizzata ed è comparsa su Google Immagini.

L'immagine del post, renderizzata attraverso JavaScript, compare su Google Immagini
L'immagine del post, renderizzata attraverso JavaScript, compare su Google Immagini

3) Gli snippet presenti su Bing e Yandex, invece, non hanno subito variazioni. Questo significa che nei giorni successivi alla pubblicazione non hanno considerato il DOM finale.

4) L'immagine indicata nel link per il preload non ha avuto un trattamento di favore rispetto all'altra.

JavaScript page rendering (β) di Yandex

Tra gli strumenti per i webmaster di Yandex è presente una funzionalità "beta" che consente di specificare come desideriamo che il robot si comporti quando scansiona le pagine.

Il pannello di configurazione del rendering di Yandex
Il pannello di configurazione del rendering di Yandex

È possibile suggerire di eseguire il JavaScript per completare il rendering, oppure di non eseguirlo. L'opzione predefinita lascia all'algoritmo la scelta sulla miglior azione da mettere in atto.

Nel caso specifico, per una pagina come quella di test, in cui quasi la totalità del contenuto viene generata lato client, ma più genericamente, ad esempio per un framework JavaScript, è consigliabile forzare il rendering.

Il rendering dinamico

Nell'ultima fase del test, ho implementato una soluzione di rendering dinamico per Bing e Yandex. Tale soluzione permette di differenziare la risposta che viene inviata al client in modo che:

  • il browser degli utenti ricevano la risposta contenente l'HTML e il JavaScript necessario a completare il rendering,
  • il crawler riceva una versione statica della pagina, contenente tutti i contenuti critici nel sorgente.
Come funziona il rendering dinamico
Come funziona il rendering dinamico

Una volta completata l'implementazione, ho richiesto nuovamente l'indicizzazione attraverso i tool di Bing e Yandex.

Yandex, in qualche ora, ha ricostruito lo snippet in SERP come segue. Quindi ha considerato i nuovi dati renedrizzati lato server.

Lo snippet di Yandex dopo il rendering dinamico
Lo snippet di Yandex dopo il rendering dinamico

Bing, invece, non ha modificato il risultato nel tempo a disposizione per il test, ma di certo l'avrebbe integrato nei giorni successivi.

Conclusioni

Questo semplice test dimostra che Google opera come da documentazione, rispettando le due fasi dello schema visto nella parte iniziale del post. Nella prima fase, infatti, ha indicizzato quasi istantaneamente i contenuti presenti nel sorgente della pagina (l'HTML generato lato server); nella seconda, in un paio di giorni, ha indicizzato le parti renderizzate via JavaScript.

Bing e Yandex, invece, non sembrano rilevare i contenuti generati via JavaScript.. almeno nei giorni successivi alla pubblicazione.

Questi elementi mettono in evidenza alcuni aspetti relativi a JavaScript che provo ad elencare.

  • Va mantenuto il focus sui mercati di riferimento per la comunicazione: se ci rivolgiamo ad un pubblico che utilizza motori di ricerca diversi da Google rischiamo di non essere visibili come vorremmo.
  • Anche se possiamo contare su Google, dobbiamo tener conto dei tempi necessari per ottenere le informazioni complete in SERP. La fase di rendering, infatti, è molto dispendiosa in termini di risorse: nel caso del test, con una sola pagina online, in qualche giorno si è ottenuto lo snippet correttamente, ma cosa accadrebbe se si trattasse di un sito web molto ampio? Il "budget" che ci mette a disposizione il motore di ricerca e le performance del sito web diventano determinanti.
Un esempio di problema SEO derivante dal rendering in JavaScript
Un esempio di problema SEO derivante dal rendering in JavaScript
  • Credo che JavaScript permetta di offrire agli utenti delle esperienze di utilizzo superiori, ma anche le competenze necessarie per raggiungere tale fine lo sono. Come SEO, dobbiamo evolverci per poter proporre le soluzioni migliori. Il pre-rendering o il rendering dinamico sono ancora fondamentali per generare i contenuti critici su progetti che devono garantire una visibilità globale.
  • Tutti i moderni framework JavaScript, che si basano sull'architettura JAMstack, come Astro, Qwik, Gatsby, Jekyll, Hugo, NuxtJS e Next.JS, offrono la possibilità di renderizzare i contenuti lato server, in modo da mettere a disposizione la versione statica delle pagine.

    Next.JS, inoltre, che secondo me è tra i più evoluti, consente una modalità di rendering "ibrida", denominata "Incremental Static Regeneration" (ISR). ISR permette la generazione delle pagine statiche in modo incrementale, con una costante elaborazione in background. Tale tecnica consente prestazioni di navigazione elevatissime.

    Qwik, dal quale sono impressionato in termini di prestazioni, consente di effettuare il rendering lato server e di ottenere un HTML per il client che necessita di meno di 1kb di JavaScript (caricato in mento di 1 ms) per essere interattivo. Tutto il resto viene scaricato in micro pacchetti quando è necessario (lazily)!
Le performance di Qwik: framework JavaScript
Le performance di Qwik: framework JavaScript
La domanda è.. vale la pena introdurre una "complessità" di questo tipo in un progetto? La risposta è semplice: sì, se produrremo un'esperienza straordinaria per l'utente!

NOTE

  • Attenzione alla differenza tra gli eventi "document ready" e "window loaded": il primo entra in azione dopo che il DOM è stato generato, mentre il secondo quando il DOM è stato generato e le risorse sono state caricate.
  • Chiaramente, per test di questo tipo, non ha senso analizzare la copia cache di Google, in quando all'apertura ri-eseguirebbe il JS, non dando la percezione dei contenuti presi in considerazione da Google.
Buon JavaScript, e buona SEO!

Per approfondire

Corso di HTML per i SEO, con un approfondimento su JavaScript

Corso di Javascript e SEO: l'indicizzazione non sarà un problema così!

Understand JavaScript SEO Basics | Google Search Central | Documentation | Google for Developers
Discover how Google Search processes JavaScript and explore best practices for improving JavaScript web apps for Google Search.
Dynamic Rendering as a workaround | Google Search Central | Documentation | Google for Developers
Dynamic rendering was a workaround for websites experiencing issues with JavaScript-powered content.
CMS Headless e JAMstack: un nuovo paradigma all’insegna delle prestazioni
L’architettura JAMstack è stata creata per rendere il web più veloce, più sicuro e più facile da scalare. E l’accoppiata tra tale architettura ed un CMS Headless, probabilmente rappresenta il futuro dello sviluppo web, verso la creazione di esperienze utente straordinarie.