Single Page Applications (SPA) kommen immer mehr in Mode und es gibt kaum noch Websites, die ohne Javascript in irgendeiner Form auskommen. Wenn Suchmaschinen eine Webseite mit Javascript crawlen, sehen sie jedoch nur die Javascript Tags. Das Script wird in der Regel nicht ausgeführt und der eigentliche Inhalt der Webseite bleibt somit verborgen. Auch die Bots sozialer Medien, wie Twitter und Facebook, verarbeiten kein Javascript und stehen quasi vor verschlossener Tür.
Was ist Prerender.io?
Prerender.io rendert Webseiten inklusive Javascript in einem Chrome Browser und liefert anschließend eine statische HTML-Seite an die Suchmaschine aus. Abhängig vom eingesetzten Webserver, wird durch eine entsprechende Konfiguration oder eine zusätzliche Middleware der Request an Prerender.io durchgereicht. Bis zu 250 Seiten im Monat sind kostenfrei, darüber hinaus gibt es gestaffelte Kostenmodelle.
Alternativ besteht die Möglichkeit, sich einen eigenen Open Source Prerender-Server aufzusetzen. Dies ist beispielsweise dann sinnvoll, wenn man sehr viele Seiten ausliefert und auf die zusätzliche Latenz durch die Hin- und Rück-Übertragung verzichten möchte. Ich habe mich für diese Lösung entschieden, weil ich gerne etwas mehr Kontrolle über die von mir eingesetzten Systeme habe. Als Basis für die Installation kommt ein Root-Server mit einem minimal Debian 10 zum Einsatz.
Headless Chrome
Für den eigentlichen Rendering-Prozess wird ein Chrome Browser benötigt. Diesen bekommt man als deb-File und kann ihn über apt leicht installieren.
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
apt install ./google-chrome-stable_current_amd64.deb
Chrome wird vom Prerender-Server später headless, also ohne GUI, ausgeführt. Ein grafisches System ist auf dem Webserver daher nicht notwendig. Bei der Installation wird das offizielle Google Repository dem System hinzugefügt.
cat /etc/apt/sources.list.d/google-chrome.list
### THIS FILE IS AUTOMATICALLY CONFIGURED ###
# You may comment out this entry, but any other modifications may be lost.
deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main
GPG-Fehler
Eventuell war meine Firewall etwas zu strikt eingestellt oder der GPG-Keyserver stand während der Installation nicht zur Verfügung. Beim Aufruf von apt-get update nach der Installation musste ich jedenfalls feststellen, dass der Public Key für das Repository nicht nicht mitgekommen ist.
W: GPG-Fehler: http://dl.google.com/linux/chrome/deb stable Release: Die folgenden Signaturen konnten nicht überprüft werden, weil ihr öffentlicher Schlüssel nicht verfügbar ist: NO_PUBKEY 78BD65473CB3BD13 E: Das Depot »http://dl.google.com/linux/chrome/deb stable Release« ist nicht signiert. N: Eine Aktualisierung von solch einem Depot kann nicht auf eine sichere Art durchgeführt werden, daher ist es standardmäßig deaktiviert. N: Weitere Details zur Erzeugung von Paketdepots sowie zu deren Benutzerkonfiguration finden Sie in der Handbuchseite apt-secure(8). Error executing command, exiting
Dieses Problem lässt sich jedoch einfach durch ein nachträgliches Abrufen des Keys beheben.
apt-key adv --keyserver hkp://pool.sks-keyservers.net:80 --recv-keys 78BD65473CB3BD13
Node.js
Der Prerender-Server läuft unter Node.js und für die spätere Installation wird der Paketmanager npm benötigt. Unter Debian 10 kann beides über apt installiert werden.
apt-get install nodejs npm
Ich habe mich stattdessen für die Installation der aktuellen Version aus dem Node Repository entschieden.
apt-get install curl
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
apt-get install nodejs
node –version
v10.20.1
npm –version
6.14.4
Prerender-Installation die Erste
Hier erstmal der schnelle Weg zum Erfolg, weiter unten dann noch eine etwas nachhaltigere Variante 😉
Die Installation des Prerender-Servers könnte kaum einfacher sein. Zuerst ein schattiges Plätzchen für die Installation aussuchen und dann über npm Prerender installieren.
mkdir /opt/prerender
cd /opt/prerender
npm install prerender
Noch die Datei server.js anlegen, in der die Parameter zum Aufruf von Chrome hinterlegt sind.
nano server.js
const prerender = require('prerender');
var server = prerender({
chromeFlags: [ ' --no-sandbox', ' --headless', ' --disable-gpu', ' --remote-debugging-port=9222', ' --hide-scrollbars' ],
logRequests: true
});
server.start();
Der Prerender-Server kann jetzt über den Aufruf von
node server.js
gestartet werden und nimmt über Port 3000/TCP URLs zum Rendern entgegen.
http://prerenderserver.tld:3000/render?url=https://rendermich.tld oder http://prerenderserver.tld:3000/https://rendermich.tld
Prerender-Installation die Zweite
Zum Testen schon ganz gut, aber ich will den Prerender-Server ja nicht immer von Hand starten. Fehlt also noch ein Init-Script. Glücklicherweise muss ich das nicht selber schreiben. Luciano Mammino hat mit Prerender-Daemon eine Lösung geschaffen, die Prerender installiert und sich auch um das Init-Script kümmert. Also die Installation von gerade eben erstmal wieder rückgängig machen.
npm remove prerender
Jetzt das Installations-Script herunterladen, auspacken und ausführen.
wget https://github.com/lmammino/prerender-daemon/archive/master.zip
unzip master.zip
cd prerender-daemon-master
./install.sh
Im Anschluss wohnt der Prerender-Server unter /usr/lib/node_modules/prerender. Dort befindet sich bereits eine Datei server.js, die ich aber noch einmal ändere.
#!/usr/bin/env node var prerender = require('./lib'); var server = prerender({ chromeFlags: [ ' --no-sandbox', ' --headless', ' --disable-gpu', ' --remote-debugging-port=9222', ' --hide-scrollbars' ], logRequests: true }); server.start();
Jetzt sollte alles soweit sein. Es ist Zeit, den Daemon zu entfesseln. Aber leider passiert… nichts. Läuft einfach nicht. Die Ursache ist schnell gefunden. Das Init-Script möchte nicht die server.js ausführen, sondern die Datei /usr/bin/prerender und läuft damit ins Leere. Abhilfe schafft ein Symlink auf die server.js.
ln -s /usr/lib/node_modules/prerender /usr/bin/prerender
Anschließend funktioniert auch der Aufruf des Daemon.
service prerender start
Der Prerender-Server läuft jetzt im Hintergrund und wird beim Neustart des Servers automatisch gestartet.
Middleware
Wie aber kommen die Requests nun vom Webserver zum Prerender-Server? Dies ist Aufgabe der Middleware und hängt von der eingesetzten Webserver-Software ab. Unter Apache beispielsweise, müssen nur eine Handvoll Module aktiviert sein. Das eigentliche Umschreiben des Request erledigen dann mod_rewrite und mod_proxy_http, z.B. in der .htaccess.
Cloaking
Cloaking wird von Suchmaschinen nicht gerne gesehen und mit Downranking in den Suchergebnissen abgestraft. Mit Prerender wird jedoch kein Cloaking im klassischen Sinne betrieben, bei dem der Suchmaschine ein anderer Inhalt als einem normalen Besucher präsentiert wird, um das eigene Ranking zu verbessern. Das genaue Gegenteil ist der Fall. Prerender hilft der Suchmaschine dabei, genau das zu sehen, was ein menschlicher Besucher sehen würde.
Bei den Suchmaschinenanbieter setzt langsam ein Umdenken ein. Interessant ist auch dieser Google Developers Beitrag zum Thema Dynamisches Rendering.