Mein kürzlich schon mal erwähntes Blogprojekt basiert, wie diese Seite hier
auch, auf einem Static Site Generator zur Erzeugung des HTML. Hier läuft
Nikola im Hintergrund, allerdings bin ich mit einigen Dingen nicht ganz so
zufrieden. Zuvorderst ist mir das Datenvolumen, welches für das Laden einer
Seite transferiert wird, viel zu groß. So werden aktuell beim Aufruf von
blog.pvitt.de
488,04 kB versendet. Davon entfallen aber nur 42,3 kB auf HTML,
dafür aber 136,39 kB auf CSS und sogar 311,13 kB auf JavaScript. Das Problem
kann man sicher über die Erstellung eines Themes angehen, aber Nikola macht es
den Nutzern durch fehlende oder schlechte Dokumentation oder komplexe Strukturen
nicht gerade einfach.
Daher habe ich für das neue Projekt nach einem alternativen Static Site
Generator umgesehen und habe einige ausprobiert. Nach einigen Tests bin ich dann
bei Pelican gelandet, der mich bisher auch nicht enttäuscht hat. Nach der
einfachen Installation und der ebenfalls einfachen Installation eines Themes
für die Seite sowie ein wenig Optimierung von CSS und mit Verwendung von SVG als
Image-Format komme ich mit zwei Testposts auf der Startseite aktuell auf ein
Transfervolumen von von 7,13 kB, 3,8 kB HTML, 2,74 kB für CSS und 609 B für SVG.
Mit Transportkomprimierung sind das sogar nur 3,85 kB, die tatsächlich über die
Leitung gehen. Das ist mal eine andere Hausnummer.
Umso ernüchterter war ich, als ich dann die Kommentarfunktion via isso
nachrüsten wollte. Denn dafür ist ein JavaScript-Paket nötig, welches zwar schon
minimiert wurde, trotzdem aber noch 54,63 kB auf die Waage (und 20,36 kB auf die
Leitung) bringt. Das ist eindeutig zu viel für eine einfache
Kommentarfunktion.
Meine Idee war nun, die Kommentarfunktionalität nur dann zu laden, wenn der
Nutzer diese auch nutzen möchte. Dazu musste ich zwar ein wenig HTML ergänzen,
aber die paar Hundert Byte fallen im Relation zu den 54 kB dann doch nicht
wirklich ins Gewicht.
Der Platzhalter im DOM, an dem das JavaScript seinen HTML-Code ablegt, blieb
unverändert im Code. Aber das Script-Tag aus dem Header habe ich entfernt:
<script data-isso="//comments.example.tld/"
src="//comments.example.tld/js/embed.min.js"></script>
Stattdessen wird dieses nun erst auf Benutzerwunsch geladen:
{% if ISSO_SITENAME %}
<input id="issoBtn" type="image" height="16" src="/theme/images/comment.svg" onclick="
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = '//{{ ISSO_SITENAME }}/js/embed.min.js';
document.body.appendChild(s);
this.style.display = 'none';
" />
{% endif %}
Das input-Tag wird (wie auch der Platzhalter) nur eingefügt, wenn ISSO auch
konfiguriert wurde. Es zeigt eine Sprechblase an, mit SVG realisiert nur 184
Byte groß. Wenn der Benutzer auf diese Sprechblase klickt, wird das JavaScript
geladen und angehängt, sodass es aktiv werden kann. Im Anschluss wird noch die
Sprechblase versteckt, da nun die Kommentare ja geladen sind.
Isso verfügt auch noch über die Möglichkeit, das clientseitige JavaScript zu
konfigurieren. Dies geschieht an Hand von data-*-Attributen, die am
Script-Element definiert werden. Da ich das Script-Element erst zur Laufzeit
erzeuge, müssen natürlich auch die Attribute zur Laufzeut erzeugt werden. Dazu
fügen wir diese Zeilen vor dem Aufruf von document.body.append
ein:
var aia = document.createAttribute('data-isso-avatar');
aia.value = 'false';
s.setAttributeNode(aia);
var aiv = document.createAttribute('data-isso-vote');
aiv.value = 'false';
s.setAttributeNode(aiv);
Mit dieser Lösung bleibt das Datenvolumen bei einem normalen Pageload klein, und
nur, wenn kommentiert werden soll, wird auch das große JavaScript nachgeladen.
Was mich an dieser Lösung noch stört, sind zwei Dinge:
- Der Leser sieht nicht, ob es schon Kommentare gibt. Hier überlege ich
aktuell noch, wie ich die Anzahl der bisher schon vorhandenen Kommentare
ermitteln kann, bevor ich das JavaScript geladen habe.
- Die Sprechblase auf der Seite wird auch dann versteckt, wenn das Javscript
nicht geladen wurde. Das ist in der Praxis sicher kein wirkliches Problem,
da im Fall, dass das JavaScript nicht geladen werden kann, wahrscheinlich die
Seite an sich oder der Server einen Knacks hat. Da wäre ein Reload der Seite
sicher besser. Aber aus Gründen der Vollständigkeit und weil ich es einfach
gern wissen würde, interessiert mich schon, wie ich den HTTP-Response für
das Script ermitteln kann.