Viele Front-End-Frameworks setzen zum Anzeigen von Inhalten JavaScript voraus. Das bedeutet, dass die Indexierung eurer Inhalte oder die Aktualisierung der indexierten Inhalte durch Google möglicherweise länger dauert.
Eine Möglichkeit, dies zu umgehen, haben wir letztes Jahr bei der Google I/O diskutiert:
dynamic rendering. Die Implementierung ist auf vielerlei Arten möglich. In diesem Blogpost implementiere ich dynamisches Rendering beispielhaft anhand von Rendertron, einer Open-Source-Lösung auf Basis der Headless-Variante von Chromium.
Für welche Websites kommt dynamisches Rendering infrage?
Nicht alle Suchmaschinen oder Bots von sozialen Netzwerken, die eure Website besuchen, können JavaScript ausführen. So benötigt etwa der Googlebot unter Umständen etwas Zeit, um euer JavaScript auszuführen. Außerdem gelten
einige Einschränkungen.
Dynamisches Rendering empfiehlt sich für häufig wechselnde Inhalte, die sich nur mit JavaScript anzeigen lassen.
Möglicherweise käme für eure Website auch eine Hybridlösung wie
Angular Universal infrage, um etwa die Zeit bis zum
First Meaningful Paint zu verkürzen.
Wie funktioniert dynamisches Rendering?
Beim dynamischen Rendering wird für bestimmte User-Agents zwischen clientseitig gerenderten und vorgerenderten Inhalten gewechselt.
Ihr benötigt einen Renderer, um JavaScript auszuführen und statische HTML-Inhalte zu erzeugen. Bei Rendertron handelt es sich um ein Open-Source-Projekt, das zum Rendern die
Headless-Variante von Chromium verwendet. Apps mit nur einer Seite laden Daten oft im Hintergrund oder stellen Aufgaben zurück, um ihre Inhalte zu rendern. Die Mechanismen von Rendertron können feststellen, wann das Rendering einer Website abgeschlossen ist. Es wird gewartet, bis alle Netzwerkanfragen beendet und alle Aufgaben erledigt sind.
Themen dieses Blogposts:
- Blick auf eine Beispiel-Web-App
- Einrichten eines kleinen express.js-Servers zur Bereitstellung der Web-App
- Installieren und Konfigurieren von Rendertron als Middleware für dynamisches Rendering
Beispiel-Web-App
Die
Web-App "Kitten Corner" nutzt JavaScript, um eine Auswahl von Katzenbildern aus einer API zu laden. Diese werden dann in einem Raster angezeigt.
|
Süße Katzenbilder in einem Raster und eine Schaltfläche zum Anzeigen weiterer Bilder – diese Web-App lässt keine Wünsche offen. |
So sieht der JavaScript-Code aus:
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);
Die Web-App verwendet modernes JavaScript (ES6). Dieses wird
vom Googlebot noch nicht unterstützt. Anhand des
Tests auf Optimierung für Mobilgeräte lässt sich herausfinden, ob der Inhalt für den Googlebot sichtbar ist:
|
Der Test ergibt, dass die Seite für Mobilgeräte optimiert ist, aber auf dem Screenshot ist nicht eine einzige Katze zu sehen. Überschrift und Schaltfläche sind vorhanden, aber keine Katzenbilder. |
Zwar lässt sich dieses Problem ganz einfach beheben, dennoch ist es eine gute Übung, was die Einrichtung von dynamischem Rendering betrifft. Dank dynamischem Rendering werden die Katzenbilder für den Googlebot sichtbar, ohne Änderungen am Code der Web-App vornehmen zu müssen.
Server einrichten
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 http://localhost:${PORT} from ${DIST_FOLDER}`);
});
Ihr könnt
das Livebeispiel hier testen. Es sollten eine Reihe von Katzenbildern zu sehen sein, wenn ihr einen modernen Browser verwendet. Damit ihr das Projekt über euren Computer ausführen könnt, benötigt ihr
Node.js zum Ausführen der folgenden Befehle:
npm install express rendertron-middleware
node server.js
Anschließend verweist ihr euren Browser auf
http://localhost:8080. Jetzt ist es an der Zeit, das dynamische Rendering einzurichten.
Rendertron-Instanz erstellen
|
Zum Erstellen eines neuen Google Cloud Platform-Projekts gibt es ein Formular. |
- Erstellt ein neues Projekt in der Google Cloud Console. Schreibt euch die Projekt-ID auf, die ihr unterhalb des Eingabefelds findet.
- Installiert das Google Cloud SDK wie in der Dokumentation beschrieben und meldet euch an.
- Klont das Rendertron-Repository aus GitHub anhand der folgenden Befehle:
git clone https://github.com/GoogleChrome/rendertron.git
cd rendertron
- Führt die folgenden Befehle aus, um Abhängigkeiten zu installieren und Rendertron auf eurem Computer zu erstellen:
npm install && npm run build
- Aktiviert den Cache von Rendertron. Dazu erstellt ihr eine neue Datei namens "config.json" mit folgendem Inhalt im Rendertron-Verzeichnis:
{ "datastoreCache": true }
- Führt den folgenden Befehl im Rendertron-Verzeichnis aus. Ersetzt "EURE_PROJEKT_ID" durch die Projekt-ID aus Schritt 1.
gcloud app deploy app.yaml --project EURE_PROJEKT_ID
- Wählt eine Region aus und bestätigt die Bereitstellung. Wartet, bis der Vorgang abgeschlossen ist.
- Gebt die URL "EURE_PROJEKT_ID.appspot.com" in euren Browser ein, wobei ihr "EURE_PROJEKT_ID" durch die jeweilige Projekt-ID aus Schritt 1 ersetzt. Ihr solltet die Benutzeroberfläche von Rendertron mit einem Eingabefeld und ein paar Schaltflächen sehen.
|
Benutzeroberfläche von Rendertron nach der Bereitstellung auf der Google Cloud Platform. |
Wenn ihr die Rendertron-Weboberfläche seht, habt ihr eure eigene Rendertron-Instanz erfolgreich bereitgestellt. Schreibt euch eure Projekt-URL (EURE_PROJEKT_ID.appspot.com) auf, da ihr sie im nächsten Teil braucht.
Rendertron dem Server hinzufügen
Der Webserver verwendet express.js und Rendertron hat eine express.js-Middleware. Führt den folgenden Befehl im Verzeichnis der Datei "server.js" aus:
npm install --save rendertron-middleware
Durch diesen Befehl wird die Rendertron-Middleware aus npm installiert, sodass wir sie dem Server hinzufügen können:
const express = require('express');
const app = express();
const rendertron = require('rendertron-middleware');
Botliste konfigurieren
Rendertron ermittelt anhand der HTTP-Kopfzeile des User-Agents, ob eine Anfrage von einem Bot oder von einem Browser eines Nutzers stammt. Hierfür steht
eine sorgfältig geführte Liste von Bot-User-Agents zum Abgleich zur Verfügung. Der Googlebot ist standardmäßig nicht in dieser Liste enthalten, weil er JavaScript ausführen kann. Wenn Rendertron auch Googlebot-Anfragen rendern soll, müsst ihr den Googlebot der Liste der User-Agents hinzufügen:
const BOTS = rendertron.botUserAgents.concat('googlebot');
const BOT_UA_PATTERN = new RegExp(BOTS.join('|'), 'i');
Rendertron vergleicht die Kopfzeile des User-Agents später mit diesem regulären Ausdruck.
Middleware hinzufügen
Damit Botanfragen an die Rendertron-Instanz gesendet werden können, müssen wir unserem express.js-Server die Middleware hinzufügen. Diese überprüft den User-Agent, von dem die Anfrage stammt, und leitet die Anfragen von bekannten Bots an die Rendertron-Instanz weiter. Fügt "server.js" den folgenden Code hinzu, wobei ihr eure Google Cloud Platform-Projekt-ID verwendet:
app.use(rendertron.makeMiddleware({
proxyUrl: 'https://YOUR_PROJECT_ID.appspot.com/render',
userAgentPattern: BOT_UA_PATTERN
}));
Bots, die die Beispiel-Website anfordern, erhalten die statischen HTML-Inhalte von Rendertron, sodass die Bots zum Anzeigen der Inhalte kein JavaScript benötigen.
Set-up testen
Wenn ihr herausfinden möchtet, ob das Rendertron-Set-up erfolgreich war, könnt ihr den Test auf Optimierung für Mobilgeräte noch einmal machen.
Im Gegensatz zum ersten Test sind die Katzenbilder nun sichtbar. Auf dem HTML-Tab sehen wir sämtliche HTML-Inhalte, die vom JavaScript-Code generiert wurden, und stellen fest, dass wir dank Rendertron kein JavaScript mehr benötigen, um die Inhalte anzuzeigen.
Fazit
Ihr habt ein Set-up für dynamisches Rendering erstellt, ohne Änderungen an der Web-App vorzunehmen. So könnt ihr Crawlern eine statische HTML-Version der Web-App bereitstellen.
Martin Splitt, Open Web Unicorn