RSS

TechTalk #29: Warte, das kann die Plattform schon selbst?

TechTalk #29: Warte, das kann die Plattform schon selbst?

Wie viele Megabyte JavaScript steckt eigentlich in einem Cookie-Banner? Diese Frage stellte sich Thomas Jaggi, Co-Founder von LegacyNotes GmbH, der einen Grossteil seiner Karriere mit dem Bau von Websites verbracht hat und nach eigener Aussage bis heute auf jede Menge überengineerte, langsame und schwer wartbare Beispiele stösst. In seinem Vortrag, dem letzten von drei Talks am TechTalk #29, baute er live dieselbe, gängige Seite zweimal nach: einmal mit einem beliebten Framework, einmal fast ausschliesslich mit Bordmitteln der Plattform.

Das Referenzprojekt

Als Ausgangspunkt diente eine ziemlich gewöhnliche Next.js-Seite: eine Blog-Übersicht, bei der einige Beiträge erst mit kurzer Verzögerung nachgeladen werden, dazu ein Consent-Overlay mit ein paar Buttons. Nichts Spektakuläres, sondern genau das Setup, zu dem viele Teams standardmässig greifen. Schon der node_modules-Ordner allein brachte es auf 570 Megabyte, grösstenteils Abhängigkeiten für Probleme, die, wie er es formulierte, die Plattform selbst mittlerweile oft bereits löst.

Nativer Nachbau

Denselben Server baute er anschliessend mit purem Node.js und ganz ohne Framework nach, wobei er Abhängigkeit für Abhängigkeit strich, sobald eine eingebaute Node-Funktion dieselbe Aufgabe übernahm: ein --watch-Flag ersetzte nodemon für den Neustart bei Dateiänderungen, natives Laden von .env-Dateien ersetzte das dotenv-Paket, das seiner Schätzung nach trotz seit einiger Zeit vorhandener nativer Node-Unterstützung weiterhin deutlich über hundert Millionen Mal pro Woche heruntergeladen wird. Als Nächstes folgte TypeScript-Unterstützung, allerdings nicht per Kompilierung, sondern über Nodes natives Type-Stripping, das eine eingeschränkte Teilmenge von TypeScript direkt ausführt (etwa ohne Enums), anstatt auf Pakete wie ts-node oder tsx zurückzugreifen, die für denselben Zweck zig Millionen wöchentliche Downloads verzeichnen.

Auch der Browser ist erwachsen geworden

Für das Öffnen und Schliessen des Consent-Dialogs selbst brauchte es überhaupt kein JavaScript mehr, dank des nativen <dialog>-Elements zusammen mit den neuen Invoker-Command-Attributen, mit denen ein Button einen Dialog rein deklarativ steuert. Übrig blieben nur noch rund 20 Zeilen Skript-Code, um die getroffene Wahl im Local Storage zu sichern, realisiert über ein Custom Element, das genau dann läuft, sobald der Browser es im DOM entdeckt. Ein Popover für denselben Dialog setzte auf die native Popover-API zusammen mit CSS Anchor Positioning, einer neuen Funktion, mit der der Browser ein Element bei Platzmangel automatisch neu positioniert, wieder ganz ohne eine einzige Zeile JavaScript.

Streaming ohne JavaScript

Am kniffligsten war das verzögerte Nachladen eines Seitenteils, der einzige Punkt, den Thomas selbst als «etwas hacky» bezeichnete: Declarative Shadow DOM verpackt den verzögerten Inhalt in ein Template-Tag, das der Browser beim Eintreffen parst. Damit lässt sich nachbilden, was Next.js mit Suspense und mehreren Megabyte mitgeliefertem JavaScript erreicht, hier aber vollständig ohne JavaScript. Für das Routing zwischen Übersicht und Detailseite kam die native URL-Pattern-API zum Einsatz statt einer Router-Bibliothek, und für die Übergänge zwischen den beiden statischen Seiten die View-Transitions-API samt ihrer neueren Cross-Document-Variante. Der Build überspringt die Animation gezielt, wenn Besucherinnen und Besucher eine reduzierte Bewegungseinstellung aktiviert haben, eine Prüfung, die sich für jede View-Transition-Umsetzung lohnt.

Der Lohn

Selbst bei komplett deaktiviertem JavaScript funktionierte die native Version durchgehend, die Next.js-Version dagegen nicht. Auf einer gedrosselten Verbindung lud die native Detailseite rund doppelt so schnell, und der Dialog erschien sofort, statt erst auf das Parsen und Ausführen von rund 650 Kilobyte JavaScript warten zu müssen.

Was wir daraus mitnehmen

Thomas selbst betonte, dass damit «die Plattform kann das jetzt auch» gemeint war, nicht eine pauschale Absage an Frameworks, auch einige seiner eigenen Beispiele brauchten noch den einen oder anderen Workaround. Der Grundgedanke dahinter gilt aber auch für uns: nine.ch selbst läuft als statische Hugo-Seite statt auf einem schweren JavaScript-Framework, aus genau den Gründen, die Thomas aufgezeigt hat: weniger, das ausgeliefert werden muss, weniger, das gewartet werden muss, weniger, das eine Seite unbemerkt ausbremsen kann. Für alle, die eigene Apps auf unserem Deploio-PaaS betreiben, gilt dieselbe Logik direkt: Ein schlankerer Dependency-Baum bedeutet schnellere Builds und einen kleineren Footprint im Betrieb, unabhängig davon, welches Framework, falls überhaupt eines, am Ende zum Einsatz kommt.

Mehr zum Deployment eigener Apps erfährst du bei Deploio, den Praxiseinsatz zeigt unsere Demokratis-Case-Study. Hast du Fragen zu einem der Themen aus dem Talk? Melde dich bei uns. Den nächsten TechTalk kündigen wir wie gewohnt über unsere Kanäle an, unter anderem in unserer Meetup-Gruppe «TechTalk @ Nine».

Kommentare & Fragen

Zum Kommentieren ist ein GitHub-Konto erforderlich.

Möchtest du auf dem Laufenden bleiben?

Abonniere unseren YouTube-Kanal und besuche den Blog unserer Website.