Lesezeit 11 Minuten

Möchte man eine eigene Webseite aufsetzen, stellt sich die Frage nach den richtigen Werkzeugen. Neben klassischen CMS (Content-Management-Systemen) stellen sogenannte Static Site Generatoren eine interessante Alternative dar. Anstatt Inhalte on demand bei jedem Seitenaufruf aus einer Datenbank zu laden und dynamisch zu rendern, werden alle Inhalte bereits im Vorfeld statisch gerendert und anschließend nur noch über einen einfachen Webserver ausgeliefert, ohne dass eine Datenbank oder sonstige aktive Komponenten auf dem Server notwendig sind.

Diese Vorgehensweise ist sicherlich nicht für alle Anwendungsfälle gut geeignet, bietet aber eine interessante Kombination von Eigenschaften, die in einigen Szenarien ihr volles Potential ausspielen kann. Dabei ist die Idee von Static Site Generatoren nicht gerade neu, jedoch kombinieren moderne Tools wie Gatsby.js diese Idee mit modernen Techniken aus der Webentwicklung, um einige der Nachteile von Static Site Generatoren zu beseitigen oder zumindest zu minimieren.

Die Anfänge des Web

Um die Idee besser zu verstehen, lohnt sich ein Blick in die Geschichte der Webentwicklung.

Los ging alles Anfang der 1990er Jahre mit der Entwicklung von HTML. Schon vorher gab es ähnliche Werkzeuge zur Auszeichnung von Dokumenten, doch die wesentliche Innovation von HTML bestand in der Möglichkeit, Verlinkungen zwischen Dokumenten vorzunehmen, ohne dass ein verlinktes Dokument darüber Kenntnis haben musste oder etwas dagegen tun könnte. Diese Flexibilität dürfte einer der wesentlichen Faktoren für den durchschlagenden Erfolg von HTML gewesen sein.

Der technische Ablauf beim Besuchen einer Webseite mit einem Browser sieht dabei vereinfacht gesagt wie folgt aus: Der Browser teilt dem Server anhand eines Unified Resource Identifiers (kurz URI) mit, welches Dokument er haben möchte. Der Webserver schaut nach, ob ein dazu passendes Dokument vorhanden ist und liefert es an den Browser zurück, welcher das Dokument darstellt.

In der Anfangszeit wurden also HTML-Dokumente einzeln geschrieben und als physische Dateien auf dem Server abgelegt. Dies hat aber mindestens zwei Nachteile: Webseiten bestehen aus vielen Unterseiten, auf denen bestimmte Teile (z.B. die Menü-Leiste) stets gleich sind. HTML kennt aber keine Möglichkeit, um bestimmte Teile wiederzuverwenden (erst mit der relativ neuen Web-Components-Spezifikation hält eine solche Möglichkeit Einzug in HTML). Daher muss der HTML-Code in allen Unterseiten kopiert werden, was sehr fehlerträchtig und unangenehm für Seitenautoren ist. Zum anderen möchte man eigentlich so gut es geht die eigentlichen Inhalte (bei einem Blog beispielsweise die Beiträge) und den Code, welcher für das Layout und ähnliches benötigt wird, trennen, was mit reinem HTML ebenfalls schwierig ist.

Da für den Browser aber irrelevant ist, wie genau der Webserver zu einer gegebenen URI das entsprechende HTML-Dokument beschafft, entstand recht bald die Idee von serverseitig laufenden Anwendungen, die on demand HTML-Dokumente erzeugen können. Hierbei werden nicht mehr fertige HTML-Dokumente von der Festplatte geladen, sondern lediglich Inhalte aus einer Datenbank abgefragt und von der Anwendung in eine HTML-Struktur eingewebt. Dies löst beide vorher genannten Probleme, da die Webanwendung zur Erzeugung der HTML-Dokumente wiederverwendbare Templates benutzen kann.

Allerdings bringen serverseitige Webanwendungen wiederum eigene Nachteile mit sich. Tendenziell dauert das Laden von Inhalten aus der Datenbank und das anschließende Generieren von HTML länger als einfach nur fertige Dateien von der Festplatte (oder sogar einem Cache) zu laden. Außerdem läuft nun eine selbst entwickelte Anwendung auf dem Server, die mehr oder weniger komplexe Logik enthält und daher selbst eine gewisse Fehlerquelle darstellt. Denn während einfache Webserver wie der Apache-Server oder Nginx einen vergleichsweise einfachen Satz an Funktionen bieten und durch den langjährigen Einsatz von unzähligen Anwendern vergleichsweise ausgereift und gestählt sind, dürfte die Fehlerwahrscheinlichkeit in selbstgebauter Software ungleich höher ausfallen.

Vorteile von Static Site Generatoren

In gewisser Weise kombinieren Static Site Generatoren diese beiden Welten. Wie bei serverseitigen Webanwendungen werden Inhalte und Templates separiert und daraus HTML-Dokumente generiert. Jedoch geschieht diese Generierung nicht on demand, wenn ein Nutzer die Webseite aufruft, sondern im Vorfeld, wenn neue Inhalte durch AutorInnen hinzugefügt wurden. Der Generator wird nicht auf dem Server ausgeführt, sondern kann z.B. auf einem einfachen Entwickler-Rechner gestartet werden.

Abbildung - die Vorteile von Static Site Generatoren

Das Resultat ist ein Satz an HTML-Dokumenten, die wie klassische Webseiten auf einen einfachen Webserver hochgeladen werden können. Der große Vorteil ist also, dass diese HTML-Dokumente nicht mehr händisch geschrieben werden müssen, sondern von einem Programm automatisch erzeugt werden. Auf dem Server läuft lediglich der Webserver und keine weiteren aktiven Anwendungen, wodurch die Angriffsoberfläche wieder drastisch reduziert wird.

Einschränkungen

Aus diesem Konzept ergeben sich aber auch zwei wesentliche Einschränkungen, die bei der Entscheidung für oder gegen Static Site Generatoren bedacht werden müssen:

  1. Während es bei serverseitigen Webanwendungen ausreicht, neue Inhalte einfach in die Datenbank einzuspielen, muss bei Static Site Generatoren die ganze Webseite neu generiert und zum Webserver hochgeladen werden, um neue Inhalte sichtbar zu machen. Für Blogs oder News-Seiten, die nur hin und wieder neuen Content bekommen, ist dies kein großes Problem, zumal der Prozess des Generierens auch weitgehend automatisiert werden kann. Für sehr dynamische Webanwendungen, die ständig neuen Content darstellen oder dessen Content stark nutzerspezifisch ist, dürften Static Site Generatoren dagegen nicht besonders geeignet sein.
  2. Da auf dem Server keine aktive Anwendung läuft, können auch keine Nutzereingaben  verarbeitet werden. Es ist also nicht ohne weiteres möglich, Inhalte dynamisch von Nutzern anlegen und verändern zu lassen. Ein Online-Editor, wie ihn CMS anbieten oder eine Kommentar-Funktion bei einem Blog ist also nicht trivial machbar.

Beide Einschränkungen sind nicht in Stein gemeißelt. Sie können gelöst werden, jedoch erfordert dies eben zusätzlichen Aufwand. Beispielsweise binden viele Blogs, die auf Basis von Static Site Generatoren gebaut sind, eine Kommentar-Funktion über einen Drittanbieter wie Disqus ein. Moderne Static Site Generatoren wie Gatsby.js können die Einschränkungen zusätzlich minimieren, indem beispielsweise beliebige Datenquellen genutzt werden können.

Doch bevor wir uns Gatsby genauer anschauen, wollen wir auf ein anderes Tool eingehen, welches sozusagen den Platzhirsch unter den Static Site Generatoren darstellt:

Jekyll

Abbildung - Logo Static Site Generator Jekyll

Das Tool „Jekyll“ wurde von GitHub entwickelt und hat wie kein zweites zur großen Popularität von Static Site Generatoren beigetragen. Vor allem in der Tech-Szene gab es vor einigen Jahren eine Welle von Umsteigern, die von klassisch gehosteten Blogging-Plattformen wie WordPress auf die aus ihrer Sicht einfachere statische Variante umgestiegen sind.

Jekyll kann prinzipiell für beliebige Webseiten genutzt werden, eine gewisse Affinität zum Blogging ist aber nicht verkennbar. Um eine Webseite mit Jekyll zu bauen, muss zunächst das Kommandozeilen-Werkzeug installiert werden, um anschließend damit ein neues Projekt zu erzeugen. Jekyll legt dabei einige Verzeichnisse sowie Konfigurations- und Template-Dateien an.

Jekyll unterscheidet zwischen „Pages“ und „Posts“.  Pages sind statische Seiten wie eine Kontaktseite, die About-Seite oder das Impressum. Posts sind dagegen eher dynamisch, beispielsweise neue Blog-Artikel. Beide Arten von Content können sowohl als HTML als auch im Markdown-Format formuliert werden. Markdown ist eine vereinfachte Auszeichnungssprache, um Text-Inhalte zu strukturieren (z.B. mit Überschriften verschiedener Ordnung) und mit Formatierungen (z.B. Kursiv oder Fett) zu versehen.

Templates werden mittels der Liquid genannten Template-Sprache erstellt. Darin wird festgehalten, wie der Content in der HTML-Seite eingebunden werden soll. Hier muss also die Struktur und das Layout der Webseite entwickelt werden. Natürlich gibt es zahlreiche Standard-Templates, die nach eigenem Geschmack angepasst und erweitert werden können.

Neben fertigen Templates stehen auch zahlreiche Plugins für Jekyll zur Verfügung, mit denen zusätzliche Funktionen wie Paginierung, die Einbindung von YouTube-Videos oder Landkarten sowie weitere Auszeichnungssprachen als Alternative zu Markdown ergänzt werden können.

Eine recht umfangreiche Liste an verfügbaren Plugins kann hier eingesehen werden.

Jekyll-Integration in GitHub

Eine Besonderheit, die Jekyll gegenüber allen anderen Static Site Generatoren hat, ist die besondere Integration in GitHub. GitHub erlaubt das Hosting von HTML-Seiten für Code-Repositories und steht somit auch für beliebige Static Site Generatoren zur Verfügung.

Allerdings muss dazu der Generierungsvorgang normalerweise lokal auf dem Rechner der Entwicklerin oder des Entwicklers durchgeführt und das Resultat anschließend auf einem bestimmten Git-Branch committed werden. Mit Jekyll kann man sich diese händischen Schritte sparen. Es reicht, wenn der reine Quellcode der Jekyll-Seite (also die Konfigurationen, Templates und Content-Dateien) in diesem Branch eingecheckt werden. Das Generieren hieraus übernimmt GitHub automatisch. Dies ist insbesondere deshalb praktisch, weil GitHub selbst einen Online-Editor für Dateien zur Verfügung stellt. Ändert man hierüber den Inhalt einer Datei, aktualisiert GitHub automatisch die Webseite. Diese Komfort-Funktion steht anderen Static Site Generatoren leider nicht zur Verfügung, sondern muss durch separate Build-Scripte nachgerüstet werden.

Nachteile von Jekyll

Neben diesen Vorteilen hat Jekyll natürlich auch einige Schwachstellen. Teilweise dürften diese aber recht subjektiv sein, weshalb ich diesen Teil auch aus meiner persönlichen Perspektive heraus schreibe.

Jekyll ist in der Programmiersprache Ruby geschrieben. Leider habe ich in der Vergangenheit die Erfahrung gemacht, dass in Ruby geschriebene Desktop-Programme nicht so einfach auf verschiedenen Betriebssystemen zum Laufen zu bekommen sind. Jekyll funktioniert meiner Erfahrung nach auf Linux-Systemen einwandfrei. Auf Apple’s Mac-OS ist es dagegen schon schwieriger, eine lauffähige Ruby-Installation mit allen notwendigen Abhängigkeiten für Jekyll aufzusetzen. Wirklich schwierig bis unmöglich wird es mit Windows-Systemen, insbesondere wenn ältere Versionen auf den aktuellen Stand geupdatet werden müssen. Die Jekyll-Seite stellt zwar auch eine Anleitung für Windows bereit, offiziell supportet wird das Betriebssystem aber nicht.

Da bei einigen Web-Projekten, die ich in der Vergangenheit mit Jekyll betrieben hatte, mehrere Autoren mit unterschiedlichsten Systemen beteiligt waren, gab es hier regelmäßig Probleme. Diese äußerten sich vor allem durch fehlende oder inkompatible Dritt-Bibliotheken und kryptische Fehlermeldungen bei Build-Problemen. Für Software-EntwicklerInnen, die in der Ruby-Welt zuhause sind und Erfahrung mit den üblichen Schwierigkeiten haben, die sicherlich jede Programmiersprache so mit sich bringt, dürften diese Probleme vermutlich weniger ins Gewicht fallen. Für uns waren sie letztlich aber der Hauptgrund, sich nach einer Alternative umzuschauen.

Gatsby

Abbildung - Logo Static Site Generator Gatsby

Gatsby.js ist ein in JavaScript geschriebener Static Site Generator, der in seiner Herangehensweise etwas komplexer, dafür aber auch wesentlich flexibler und mächtiger als viele andere Generatoren ist.

Gatsby ist stark plugin-orientiert. Es trennt dabei zwischen „Source-Plugins“ und „Transformer-Plugins“. Source-Plugins stellen Daten aus einer bestimmten Datenquelle zur Verfügung. Das wichtigste davon ist das Filesystem-Plugin. Mit ihm können Dateien als Quelle definiert werden, wobei auch mehrere Instanzen des Plugins für verschiedene Unterverzeichnisse konfiguriert werden können. Es gibt aber auch Source-Plugins, die Daten zum Beispiel aus Quellen wie Datenbanken, REST-APIs oder anderen Diensten beziehen können. Beispielsweise gibt es Plugins zur Einbindung von WordPress, wodurch Artikel in WordPress verfasst und anschließend durch Gatsby verarbeitet werden können. Ein weiteres Beispiel ist ein Source-Plugin zur Einbindung eines ICAL-Kalenders. Auf diese Weise können u.a. Veranstaltungstermine auf einer Website aufbereitet werden.

Welche Form die vom Source-Plugin zur Verfügung gestellten Daten besitzen, ist dabei nicht vorgegeben. Hierfür kommen die Transformer-Plugins zum Einsatz: Der Klassiker hier wäre wieder ein Markdown-Plugin aber auch andere Quell-Formate können flexibel eingesetzt werden, beispielsweise um JSON-Dateien oder Bilder zu verarbeiten.

Datenverwaltung mittels GraphQL

Die Plugins stellen die Daten allgemein zur Verfügung. Wie und in welcher Form diese nun zur Generierung von konkreten Webseiten genutzt werden, ist wiederum flexibel konfigurierbar. Gatsby stellt dazu ein dynamisch erzeugtes GraphQL-Schema bereit.

GraphQL ist eine Daten-Abfragesprache, die eigentlich für Web-APIs entwickelt wurde. Diese erlaubt es, JSON-ähnliche Queries an einen Server zu schicken und dazu passende Antworten in JSON zu erhalten. Welche Daten verfügbar sind und wie diese zusammenhängen, legt ein GraphQL-Schema fest. Dieses definiert Datentypen und mögliche Abfragemethoden.

Bei Gatsby gibt es keinen Server, jedoch stellt Gatsby während des Build-Prozesses ein GraphQL-Schema bereit, welches die Daten der konfigurierten Plugins zentral zur Verfügung stellt. In Code-Block 1 ist ein beispielhafter GraphQL-Query zu sehen, der alle Markdown-Texte, inklusive einiger Meta-Daten (bei Markdown als „frontmatter“ bezeichnet), abfragt. Das Ergebnis ist eine JSON-Liste von Artikeln mit genau den abgefragten Feldern.

{
allMarkdownRemark {
edges {
node {
frontmatter {
title
date
author
}
html
}
}
}
}

Code-Block 1

Darstellung mit React

Zur Darstellung der Daten nutzt Gatsby die UI-Bibliothek React. Dazu legt man eine JavaScript-Datei und den zu dieser Datei gehörenden GraphQL-Query als exportierte Konstante mit der Bezeichnung „query“ an. Gatsby nutzt diese Namenskonvention um die Komponente mit den richtigen Daten zu befüllen. Anschließend baut man die React-Komponente, die die Ergebnisse des Queries als Eingabedaten entgegen nimmt und nach eigenen Wünschen in HTML umwandelt. Code-Block 2 zeigt ein entsprechendes Beispiel, welches alle Artikel untereinander auflistet.

// index.js
import React from "react"
import { graphql } from "gatsby"

export const query = graphql`
query {
allMarkdownRemark {
edges {
node {
id
frontmatter {
title
}
html
}
}
}
}
`

export default ({data}) => (
<div>
<h1>Hello World Blog</h1>
{
data.allMarkdownRemark
.edges.map(edge => edge.node)
.map(node => (
<div key={node.id}>
<h2>{ node.frontmatter.title }</h2>
<div dangerouslySetInnerHTML={{__html: node.html}} />
</div>
))
}
</div>
)

Code-Block 2

Die eigentliche React-Komponente ist die mittels „export default“ exportierte Funktion, welche die Daten der Query als Parameter bekommt. Über die Artikel wird mittels „map“-Funktion iteriert und für jeden Artikel ein eigener DIV-Container erzeugt.

Die Angabe „dangerouslySetInnerHTML“ ist eine Besonderheit von React. Das Markdown-Plugin stellt uns den Text bereits als HTML zur Verfügung. Allerdings erlaubt React das Einbinden von fertigem HTML aus Variablen nicht einfach so, da dies eine häufige Fehlerquelle und ein Sicherheitsrisiko darstellt. Um auf dieses Risiko hinzuweisen, wurde die Funktion, um dennoch HTML direkt einfügen zu können, entsprechend benannt. In unserem Fall ist dies okay, denn wir wissen, dass der HTML-Code nicht direkt von Nutzern (und damit potentiellen Angreifern) stammt, sondern durch den Markdown-Parser erzeugt wurde.

Abbildung - Gatsby Plugin Architektur

Gatsby Plugin Architektur

Static Site kombiniert mit Single-Page-App

Die hier gezeigte Trennung in einzelne Arbeitsschritte und jeweils dazugehörige Plugins, sowie die Kapselung in ein gemeinsames GraphQL-Schema und die Darstellung mittels React-Komponenten, ist einer der wichtigsten Eigenschaften von Gatsby. Denn genau diese Architektur ist für die große Flexibilität verantwortlich.

Ein weiterer Vorteil ist der Einsatz von React und damit eines modernen Frontend-Frameworks. Denn obwohl Gatsby weiterhin ein statischer Seitengenerator ist, lassen sich dennoch dynamische Aspekte realisieren. Das Resultat, welches Gatsby am Ende des Build-Prozesses ausspuckt, ist weiterhin ein Satz statischer HTML-, CSS- und JavaScript-Dateien, die auf einen normalen Webserver ohne Datenbank oder Anwendungsserver ausgeliefert werden können. Im Browser des Nutzers setzt sich daraus aber eine vollwertige React-Single-Page-Applikation zusammen.

Das bedeutet zum Einen, dass auch dynamische React-Komponenten, die Benutzerinteraktionen erlauben, in die Seite eingefügt werden können. Zum Anderen sind Aspekte wie eine nahtlose Navigation zwischen Unterseiten ohne vollständigen Seiten-Reload, wie man es von modernen Single-Page-Apps erwartet, bereits standardmäßig abgehandelt.

Interessanterweise sind Gatsby-Seiten dennoch auch ohne aktiviertes JavaScript nutzbar, wobei dann natürlich spezielle interaktive React-Komponenten nicht mehr funktionieren. Die Seite verhält sich dann wie jede andere statische HTML-Seite auch, inklusive Site-Reloads beim Wechsel zwischen Unterseiten. Dies ist insbesondere für Suchmaschinenoptimierung (SEO) wichtig, denn ein Suchmaschinen-Crawler sieht auch ohne JavaScript konkrete Inhalte auf der Webseite, die er für die Indexierung nutzen kann.

Durch die Bereitstellung einer Single-Page-App und durch die Möglichkeit der Verwendung von nahezu beliebigen Datenquellen verkleinert Gatsby die Lücke zwischen normalen statischen Seiten und vollwertigen Webanwendungen. Es bleibt aber auch bei Gatsby dabei, dass neue Inhalte immer einen Re-Build der Seite bedürfen. Der gesamte oben geschilderte Prozess läuft nach wie vor nur einmal zum Build-Zeitpunkt ab und nicht on demand sobald NutzerInnen die Webseite aufrufen.

Optimierung der Ladegeschwindigkeit

Ein weiterer Aspekt, dem die Gatsby-Entwickler große Aufmerksamkeit widmen, ist die Optimierung der gefühlten Geschwindigkeit der End-Nutzer. Im Vergleich zu anderen Static Site Generatoren ist die Zeit, die das Generieren der Seite aus den Quell-Dateien benötigt, relativ lang. Dafür ist die generierte Seite darauf optimiert, für die eigentlichen Nutzer der Seite im Browser möglichst schnell verfügbar zu sein. Anders als bei reinen Single-Page-Apps, die ihre Darstellung nur client-seitig generieren und dadurch erst verfügbar sind, nachdem die JavaScript-Ausführung abgeschlossen ist, liegen Gatsby-Seiten bereits vorgerendert auf dem Server. Dadurch können bereits Inhalte dargestellt werden, bevor die React-Anwendung „hochgefahren“ ist.

Darüber hinaus unterstützt Gatsby so genanntes Pre-Loading: Gatsby lädt nur die jeweils sichtbare Seite, wodurch die zu übertragende Datenmenge zunächst recht klein ist. Sobald der Nutzer über einen Bereich scrollt, der einen Link zu einer anderen Unterseite enthält, beginnt Gatsby damit, diese Unterseite zu laden. Klickt der Nutzer auf diesen Link, stehen die Daten bereits zur Verfügung, und die Navigation zur Unterseite kann sofort stattfinden.

Ein anderer Optimierungsschritt ist die besondere Verarbeitung von Bildern: Bilder sollten in Gatsby in möglichst hoher Auflösung vorliegen. Im Build-Prozess erzeugt Gatsby daraus verschiedene Versionen in unterschiedlichen Auflösungen und Dateigrößen. Zur Laufzeit werden nur die Versionen herangezogen, die für die jeweilige Bildschirmgröße sinnvoll sind. Öffnet man die Seite beispielsweise auf dem Smartphone mit schlechter Internetverbindung, wird zunächst eine sehr pixelige Version angezeigt, die noch keine Details erkennen lässt, aber zumindest schonmal andeutet, dass hier ein Bild kommt. Im Hintergrund wird nun eine zur Displaygröße passende Version des gleichen Bildes geladen und ausgetauscht, sobald diese fertig heruntergeladen wurde. Für NutzerInnen ergeben sich daraus Vorteile bei der User Experience.

Fazit

Als Fazit lässt sich sagen, dass Static Site Generatoren allgemein und Gatsby im Besonderen eine interessante Alternative zu klassischen serverseitigen Webanwendungen darstellen. Besonders wenn eine Seite vor allem redaktionelle Inhalte oder eher statische Seiten enthält, was beispielsweise bei Firmen-Webseiten der Fall ist, bieten sich Static Site Generatoren an. Auch für technische Dokumentationen kommen diese Werkzeuge häufig zum Einsatz. Mit Gatsby lässt sich darüber hinaus die Grenze zwischen statischen Web-Inhalten und dynamischen Single-Page-Apps verschieben. Eine umfangreiche Liste mit Webseiten, die auf Gatsby basieren, findet sich auf der Projektseite.

Sie möchten mehr über Static Site Generatoren erfahren? In diesem Artikel haben wir Ihnen eine Übersicht der beliebtesten Generatoren zusammengestellt. 

Manuel Mauky

Manuel Mauky ist Softwareentwickler bei der Saxonia-Systems AG in Görlitz. Er beschäftigt sich dort vor allem mit Java- und Webentwicklung sowie Softwarearchitektur. Daneben interessiert er sich für funktionale Programmierung. Er spricht regelmäßig auf Konferenzen und User-Groups und ist Organisator der Java-User-Group Görlitz.
Manuel Mauky

Letzte Artikel von Manuel Mauky (Alle anzeigen)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Die von Ihnen hier erhobenen Daten werden von der Host Europe GmbH zur Veröffentlichung Ihres Beitrags in diesem Blog verarbeitet. Weitere Informationen entnehmen Sie bitte folgendem Link: www.hosteurope.de/AGB/Datenschutzerklaerung/