von Sven Koelpin
Eine langfristige technologische Sicherheit ist für viele Unternehmen ein essenzieller Faktor. Anders als zum Beispiel beim Enterprise-Java-Standard, der über einen langen Zeitraum stabile APIs und weitestgehend gleichbleibende Programmierkonzepte garantiert, hat es eine solche Stabilität in der Welt der Web-Frontends zuletzt nicht gegeben. Vielmehr hat es hier den Anschein, als ob alle paar Wochen neue Frameworks, Tools oder Best Practices das Licht der Welt erblicken. Jede dieser Neuerungen scheint dabei das Web zu revolutionieren – die Autoren behaupten das zumindest. Eine Folge davon: Was heute noch als guter Frontend-Stack betitelt wird, ist ein Jahr später oftmals nicht mehr State of the Art.
Single-Page Applications: Angular, React, Vue.js?
Im Blogeintrag [1] „The Brutal Lifecycle of JavaScript Frameworks“ wurde der Lebenszyklus von JavaScript-Frameworks auf Basis von Daten der Stack-Overflow-Trends-Tools [2] analysiert. Die Ergebnisse veranschaulichen zwei Dinge (Abb. 1). Auf der einen Seite ist die Schnelllebigkeit vieler SPA-Frameworks zu erkennen. Diese durchleben zumeist in einer kurzen Zeit einen raschen Anstieg, haben aber nach spätestens zwei bis drei Jahren so gut wie keine Relevanz mehr am Markt. Auf der anderen Seite ist aber auch zu erkennen, dass sich neben den zahlreichen und kurzlebigen „kleineren“ SPA-Frameworks mit Angular und React zwei Big Player herauskristallisiert haben. Diese beiden SPA-Frameworks werden von je einem Technologiegiganten, Angular von Google und React von Facebook, entwickelt. Sowohl Angular als auch React verzeichnen seit über zwei Jahren ein starkes Wachstum, und es ist nicht zu erwarten, dass sich dieser Aufschwung in absehbarer Zeit signifikant abschwächen wird.
Auch Vue.js hat im letzten Jahr deutlich an Aufschwung erfahren, obgleich die Nutzungszahlen die der beiden großen Frameworks noch lange nicht erreichen. Der Anstieg bei Vue.js ist vermutlich nicht zuletzt darauf zurückzuführen, dass für den Einstieg keine unbedingte Notwendigkeit dazu besteht, in die oftmals überwältigende Welt der modernen JavaScript-Entwicklung einzutauchen [3].
Man kann natürlich nicht behaupten, dass die Daten von Stack Overflow die Realität von Nutzungszahlen in ihrer Vollkommenheit widerspiegeln. Sie bieten aber dennoch einen guten Überblick über die aktuelle Welt der SPA-Frameworks und bestätigen, dass das Gesamtinteresse an Single-Page Applications in den letzten Jahren um ein Vielfaches angestiegen ist.
Abb. 1: Der brutale Lebenszyklus der JavaScript Frameworks (Erstellt mit Stack Overflow Trends)
Ist wirklich alles unsicher?
Die Schnelllebigkeit in der Welt der Web-Frontends ist zwar immer ein großer Unsicherheitsfaktor, es lässt sich aber nicht bestreiten, dass die Veränderungen der Frameworks und Tools in den letzten Jahren das Entwicklerleben stark vereinfacht und Single-Page Applications erst richtig Enterprise-fähig gemacht haben. Das beste Beispiel dazu ist der Sprung von AngularJS zu Angular, bei dem das Framework grundlegend verändert und damit ein wichtiger Grundstein für die moderne SPA-Entwicklung gelegt wurde.
Derartige Big-Bang-Versionssprünge werden sich aber in Zukunft, zumindest bei den großen Frameworks Angular und React, wohl kaum wiederholen. Die Community hinter diesen Bibliotheken wird immer stärker – und dass die Nutzergemeinde durchaus Einfluss auf die Entscheidungen der Frameworkhersteller haben kann, hat sich eindrucksvoll bei der Lizenzänderung von React im letzten Jahr gezeigt.
Mittlerweile bieten SPA-Frameworks zudem meistens sinnvolle Vorgehensmodelle und Tools, um mit Breaking Changes umzugehen. So gibt es zum Beispiel bei React die Regel, dass Breaking Changes des API eine Major-Version lang in der alten und neuen Variante unterstützt werden, bevor nur noch das neue API zur Verfügung steht. Zudem gab es bisher immer Tools [4], die eine bestehende Codebasis weitestgehend automatisiert auf neue Patterns oder APIs migrieren konnten. Dieses Vorgehen ist sicherlich auch eine Folge davon, dass Facebook React selbst aktiv im Einsatz hat.
Auch wenn Angular und React mittlerweile einen Großteil der SPA-Gemeinde bedienen, schwächt das die Innovationskraft der JavaScript-Community noch lange nicht ab. Bei der Menge an neuen Tools, Patterns und Best Practices fällt es so oftmals schwer, den Überblick zu behalten (aka „JavaScript Fatigue“). Anstatt sich aber von der Vielzahl der neuen Dinge verunsichern zu lassen, sollte diese Entwicklung eher positiv gesehen werden. Schließlich befeuern die neuen Frameworks und Werkzeuge, die in einigen Aspekten sogar besser und schneller sind als die „Großen“, den Wettbewerb und lassen diese in Zugzwang geraten (z. B. webpack vs. Parcel, React vs. Preact).
SPAs vorausschauend entwickeln
Es wäre sicherlich blauäugig, davon auszugehen, dass die aktuelle Welt der Web-Frontends in zwei bis drei Jahren noch die gleiche ist wie heute. Zwar ist nicht zu erwarten, dass die „großen“ SPA-Frameworks dann keine Relevanz mehr haben. Es ist durch die ständige Weiterentwicklung der Plattform „Web“ aber wahrscheinlich, dass sich Single-Page Applications und damit auch die Frameworks stetig neuen technischen Herausforderungen und Anforderungen stellen müssen. Und das ist in gewisser Weise auch gut so, denn das Web ist als Applikationsplattform aktuell noch weit davon entfernt, perfekt zu sein.
Wer heute schon SPAs entwickelt, dem bleibt also nichts anderes übrig, als die hohe Dynamik in diesem Bereich für die eigene Anwendung abzufedern. Das lässt sich beispielsweise mit einer robusten Web-Frontend-Architektur ausprobieren. Glücklicherweise haben sich in den letzten Jahren nicht nur SPA-Frameworks, sondern weitestgehend auch architektonische Prinzipien in Single-Page Applications manifestiert. Die Verwendung dieser kann die Basis für eine robuste SPA-Architektur legen und sie widerstandsfähiger gegen etwaige zukünftige Veränderungen der Außenwelt gestalten.
Der Web Development & JavaScript Track auf der W-JAX 2018
SPAs komponentenbasiert entwickeln
Die meisten der aktuell relevanten SPA-Frameworks arbeiten komponentenbasiert. Bei dieser Art von Single-Page Applications wird die gesamte Anwendung auf Basis von Komponenten, die in einer Baumstruktur organisiert sind, implementiert. Häufig werden die Komponenten einer Applikation in Smart Components und Dumb Components unterteilt (Abb. 2).
Dumb Components haben ihren Namen aus dem Grund, dass sie im Sinne des Wissens über den aktuellen Gesamtstatus einer Applikation „dumm“ sind. Sie bekommen die Daten, auf denen sie operieren, ausschließlich über ihre Elternkomponenten hereingereicht. Natürlich können Dumb Components trotzdem auch komplexe Logik enthalten, sie sollten aber weitestgehend wiederverwendbar und flexibel an verschiedenen Stellen einer Applikation einsetzbar sein. Klassische Beispiele für Dump Components sind Listen, Tabellen oder Eingabefelder. Sie werden häufig nicht selbst entwickelt, sondern können auch aus Komponentenbibliotheken [5], [6] bezogen werden.
Smart Components haben Zugriff auf den Gesamtstatus der Anwendung. Sie sind deshalb häufig mit den Services (zumeist bei Angular) oder Stores (zumeist bei React) der Applikation verbunden und verteilen die Daten an die unterliegenden Komponenten weiter. Smart Components sind häufig die Einstiegspunkte zu bestimmten Bereichen einer Anwendung. Sie kapseln also ganze Seiten oder Bereiche von Seiten, die bestimmte Use Cases abbilden.
Die Verwendung von Smart und Dumb Components hat sich bisher als gutes Mittel für die Strukturierung einer komponentenbasieren SPA erwiesen. Sie können dabei helfen, die Architektur weniger anfällig für grundlegende technische Veränderungen zu machen.
Abb. 2: Smart vs. Dumb Components
State-Management überdenken
Anders als bei serverseitig gerenderten Webanwendungen, deren Applikationsdaten zumeist nur auf dem Server verwaltet werden, liegen bei Single-Page Applications Teile des Applikationsstatus im Client (Application State). Dieser Status kann vielfältig sein, und die Verwaltung und Manipulation sind häufig alles andere als trivial. Der Application State lässt sich in Domain State (domänenbezogener Status, häufig „Entities“), UI State (UI-bezogener Status, z. B. „Ist ein Modaldialog geöffnet?“) und Component State (z. B. „aktueller Text in einem Textfeld“) unterteilen. Zusätzlich haben die Daten zumeist noch eine unterschiedliche Lebensdauer. Man unterscheidet hier zwischen Short-Term State (flüchtige Daten), Medium-Term State (Daten, die die gesamte Applikationslebensdauer überleben) und Long-Term State (Daten, die auch nach dem Schließen der Anwendung noch existieren).
Die Kombination der verschiedenen States und die unterschiedliche Lebensdauer der Daten kann zu sehr komplexen Datenflüssen führen. Bei komponentenbasierten Single-Page Applications hat sich zur Abschwächung dieser Komplexität das Flux-Pattern (auch Flux-Architektur) durchgesetzt. Es gibt verschiedene Abwandlungen und Implementierungen von Flux, die bekannteste ist Redux [7]. Zugrunde liegt die Idee, dass Teile des Application States zentral verwaltet werden und jegliche Daten stets unidirektional, also nur in eine Richtung, fließen. Dabei werden Änderungen des Application States an Smart Components propagiert, die die jeweiligen Datenänderungen wiederum an die Dumb Components weitergeben können (Abb. 2).
Unidirektionale Datenflüsse eignen sich sehr gut bei hierarchischen Komponentenbäumen, wie wir sie in den meisten SPAs finden. Deshalb gibt es von den bekanntesten Flux Libraries in der Regel auch Implementierungen für alle großen SPA-Frameworks.
Für eine robuste und nachhaltige SPA-Architektur kann es sinnvoll sein, eine State-Management-Library einzuführen und so die Verwaltung des Applikationsstatus vom Single-Page-Application-Framework zu trennen. Allerdings gibt es auch oftmals Fälle, in denen ein externes State-Management mehr Arbeit macht, als dass es Nutzen bringt. Der Einsatz sollte deshalb abhängig von der Komplexität der Applikation und des zu verwaltenden Status, nicht aber unbedingt von der Größe der Anwendung, gemacht werden.
Wie mit ständigen Updates umgehen?
Bei Angular und React standen in den letzten beiden Jahren ungefähr alle sechs Monate neue Major-Releases an – teilweise mit rudimentären Änderungen der APIs. Zwar gibt es, wie bereits erwähnt, zumeist einigermaßen schmerzfreie Migrationspfade. Diese funktionieren aber nur problemlos, wenn vorher bereits regelmäßig aktualisiert wurde. Noch dazu kommen ständige Versionsänderungen in etwaigen anderen Paketen und Tools, die man für die Entwicklung einer SPA benötigt. Um hier nicht abgehängt zu werden, ist es sinnvoll, regelmäßig die Versionen der installierten Pakete zu überprüfen und gegebenenfalls frühzeitig zu aktualisieren. Das Überprüfen der Versionen kann manuell oder mithilfe von Tools erreicht werden. Beispielsweise können Versionschecks automatisiert in den Build-Prozess eingebunden werden (z. B. mit npm-check-updates [8]). Für eine robuste SPA-Architektur ist es zum aktuellen Zeitpunkt unbedingt nötig, Versionsupdatemanagement als regelmäßigen Workflowschritt zu installieren.
Free: Mehr als 40 Seiten Java-Wissen
Lesen Sie 12 Artikel zu Java Enterprise, Software-Architektur und Docker und lernen Sie von W-JAX-Speakern wie Uwe Friedrichsen, Manfred Steyer und Roland Huß.
Fazit
Wer heute auf SPAs setzt, ist schon viel besser dran, als noch vor zwei Jahren – das Umfeld ist spürbar erwachsener geworden. Beispielsweise wurde für AngularJS, dem Vorgänger von Angular, Anfang des Jahres eine dreijährige Long-Term-Support-Version angekündigt, und das obwohl das Framework im Gegensatz zur Neuauflage stetig an Nutzern verliert – ein wichtiges Signal in Richtung der Community [9]. Eine gleiche Sicherheit wie bei Enterprise Java gibt es aber dennoch selbstverständlich nicht. Die hohe Dynamik der SPA-Welt ist aber nicht nur kritisch zu betrachten. Während standardgetriebene Frameworks wie Enterprise Java zwar eine langfristige Sicherheit bieten, glänzten sie bislang nicht gerade mit kurzen Innovationszyklen , wobei sich das natürlich mit EE4J ändern könnte. SPA-Frameworks hingegen bieten die Möglichkeit, technologische Trends schnell umzusetzen und so näher an den Erwartungen der Benutzer zu agieren – selbstverständlich zum Preis der Nichtexistenz von klar definierten Standards und langfristiger Garantien.
Komponentenbasierte Benutzungsoberflächen gibt es schon lange. Dass sich dieses Architekturprinzip nun auch wieder bei allen namenhaften SPA-Frameworks manifestiert hat, ist ein klares Signal für die Zukunft: Es ist aller Wahrscheinlichkeit nach davon auszugehen, dass komponentenbasierte Single-Page Applications auch weiterhin eine Rolle spielen werden. Deshalb kann eine saubere Komponentenarchitektur in Verbindung mit einem durchdachten State-Management und regelmäßigen Versionsupdates dabei helfen, eine robuste und hoffentlich zukunftssicher SPA-Architektur gestalten. In diesem Sinne: Stay tuned!
Links & Literatur
[1] Stack Overflow: „The Brutal Lifecycle of JavaScript Frameworks“: https://stackoverflow.blog/2018/01/11/brutal-lifecycle-javascript-frameworks/
[2] Stack Overflow Trends Tools: https://insights.stackoverflow.com/trends
[3] Vue.js: https://vuejs.org/v2/guide/comparison.html#Learning-Curve
[4] react-codemod: https://github.com/reactjs/react-codemod
Erfahren Sie mehr über Web Development:
● Micro Apps mit Angular Elements und Web Components – Eine perfekte Kombination?
● Erfolgreiches User Onboarding: Wie Sie den Anwender am richtigen Punkt abholen