Im Folgenden möchte ich dir verschiedene Micro-Frontend-Arten vorstellen und erklären, wie du Micro-Frontends im Rahmen moderner Frontend-Entwicklung einsetzt. Da jede Art ihre Vor- und Nachteile besitzt, werde ich im Anschluss eine Vergleichsmatrix der Micro-Frontend-Typen präsentieren, damit du die einzelnen Micro-Frontend-Arten besser einordnen kannst.
Bei multiple URL-based SPAs werden die einzelnen Micro-Frontends unter separaten URLs bereitgestellt. Dabei kann jedes Frontend mit einer beliebigen Technologie umgesetzt werden. Jedes Frontend besitzt sein eigenes Backend, über das auch die Kommunikation zu anderen Frontends stattfindet. Wenn beispielsweise Frontend A etwas von Kontext B wissen will, fragt Frontend A (wie in Abbildung 1 zu sehen ist) sein eigenes Backend.
Bei dieser Art von Micro-Frontend ist es natürlich nicht zwingend erforderlich, dass die jeweiligen Teams mit unterschiedlichen Technologien arbeiten. Die Praxis zeigt, dass man das aufgebaute Wissen über eine Technologie in einem Projekt nicht unterschätzen sollte. Auch die teamübergreifende Unterstützung bei auftretenden Problemen oder das Auswechseln von Entwicklern wird stark vereinfacht.
Abb. 1: Multiple URL-based SPA Architektur
Bei Pure Web Components werden die Micro-Frontends über Standard Web Components realisiert.
„Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps. Custom components and widgets build on the Web Component standards, will work across modern browsers, and can be used with any JavaScript library or framework that works with HTML.”
Quelle: https://www.webcomponents.org/introduction#what-are-web-components
Die jeweiligen Komponenten werden dabei über einen Packet Manager (z. B. NPM oder yarn) veröffentlicht. Ein übergeordneter Composition Layer hat die Aufgabe, alle Komponenten zu laden und diese anschließend in einer Gesamtapplikation zu rendern.
Für die Integration der einzelnen Komponente in dem Composition Layer werden z. B. HTML-Imports verwendet (siehe Code-Beispiel unterhalb), wodurch Web Components innerhalb einer Applikation bekannt gemacht werden können:
<my-component any-attribute="foo"></my-component>
<link rel="import" href="./my-component.html">
Die Kommunikation zwischen den Frontends (Teams) erfolgt bei dieser Art von Micro-Frontend, wie in Abbildung 2 zusehen ist, über einheitliche Custom Events. Jedes Event ist mit einem speziellen Präfix für das jeweilige Team versehen. Die Initialisierung der Web Components erfolgt über das Setzen von HTML-Attributen.
Der Fokus wird daher sehr stark auf die Verwendung der HTML bzw. ECMAScript Standards gesetzt – ein guter Schritt in Richtung technologischer Unabhängigkeit. Doch die Mächtigkeit und der Reifegrad von Web Components ist im Gegensatz zu klassischen Framework Components noch nicht sehr ausgereift.
Abb. 2: Pure Web Components Architektur
Beim Ansatz mit Framework Components werden die einzelnen Micro-Frontends über UI-Komponenten realisiert. Diese wurden zuvor in einem Web Application Framework wie z. B. Angular, Vue oder React entwickelt. Auch bei diesem Ansatz werden die einzelnen Komponenten über einen Packet Manager veröffentlicht und anschließend über einen übergeordneten Composition Layer gerendert.
Framework Components unterscheidet man in zwei Varianten:
Bei dieser Variante erfolgt die Kommunikation zwischen den Micro-Frontends direkt über eine Public API auf dem Client. Die einzelnen Komponenten der Frameworks stellen hier Schnittstellen zur Verfügung, damit sie mit anderen Komponenten kommunizieren können.
Abb. 3: Framework Components Architektur Variante 1
Bei dieser Variante erfolgt die Kommunikation zwischen den Frontends über ihr jeweils eigenes Backend. Die einzelnen Komponenten der Frameworks stellen Anfragen an ihr eigenes Backend, welches wiederum Anfragen an einen externen Micro-Service im Backend schickt, um an die Informationen zu gelangen.
Abb. 4: Framework Components Architektur Variante 2
Beide Framework-Components-Varianten haben den großen Vorteil, dass sie auf den vollen Funktionsumfang des jeweiligen Web-Applikation-Frameworks zurückgreifen können, wodurch sie sehr mächtig werden. Der direkte Nachteil bei dieser Art ist, dass man das jeweilige Framework im Composition Layer laden muss, da die Framework Components nur in dem jeweiligen Kontext lauffähig sind.
Bei Framework Web Components werden die Frontends über Web Components realisiert, die ebenfalls über ein Web-Applikation-Framework erstellt wurden.
Diese über das Framework erstellten Web Components, sind ebenfalls nur im jeweiligen Framework-Kontext lauffähig, da es keine gewöhnlichen Web Components sind – es sind sozusagen Framework Components, die sich nur nach außen als Web Components präsentieren. Man kann sie mithilfe von speziellen Framework Funktionen erzeugen (siehe nachfolgendes Codebeispiel):
Angular: createCustomElement(ButtonComponent);
Vue: wrap(Vue, VueWebComponent);
Veröffentlichung und Rendern erfolgen bei dieser Art von Micro-Frontend analog zu den anderen Ansätzen. Die Kommunikation zwischen den Frontends erfolgt hier ebenfalls über einheitliche Custom Events.
Abb. 5: Framework Web Components Architektur
Diese Art von Micro-Frontends setzt den Fokus wie auch die Pure Web Components auf die Verwendung der HTML bzw. ECMAScript Standards, was auch hier ein guter Schritt in Richtung technologischer Unabhängigkeit ist. Doch bei diesem Ansatz kann man darüber hinaus auch auf den Funktionsumfang des eingesetzten Web-Applikation-Frameworks setzen, was ein klarer Vorteil gegenüber Pure Web Components ist.
Doch die Tatsache, dass es sich hier nur um Framework Components handelt, die als Custom Elements bzw. Web Components verpackt wurden, hat zur Folge, dass auch sie nicht ohne einen Framework-Kontext lauffähig sind.
Bei Self-Contained Framework Web Components werden die Micro-Frontends über ganz spezielle Web Components realisiert. Diese vom Framework erzeugten Web Components sollen ihr eigenes Web Framework als minimal self-contained version mitbringen.
Somit wären diese Micro Frontends auch in anderen Kontexten lauffähig. Veröffentlichen, Rendern und die Kommunikation würde wieder analog zu Framework Web Components erfolgen. Das Angular-Team von Google arbeitet derzeit im Rahmen des “Custom Elements & Ivy Rendering Engine”-Projektes an diesem Ansatz:
„We are working on custom elements that can be used by web apps built on other frameworks. A minimal, self-contained version of the Angular framework will be injected as a service…”
Quelle: https://angular.io/guide/elements
Abb. 6: Self-Contained Framework Web Components Architektur
Self-Contained Web Components hätten den großen Vorteil, dass man bei der Technologiewahl völlig frei wäre und trotzdem den vollen Funktionsumfang des eingesetzten Web-Applikation-Frameworks nutzen könnte.
In der Realität müsste man es sich allerdings sehr gut überlegen, ob diese Entscheidung für ein Projekt wirklich sinnvoll ist, da eine Web-Applikation auch immer im Hinblick auf Ladezeiten entwickelt werden sollte.
Denn würde jedes Team ein anderes Framework wählen, müssten auch im Client alle eingesetzten Frameworks geladen werden. Dies macht spätestens bei geringen Bandbreiten keinen Sinn mehr.
Mosaic9 ist der Ansatz auf den Zalando setzt und ist erstmal eine Sammlung von Diensten und Bibliotheken mit einer Spezifikation. Diese Spezifikation beinhaltet Definitionen von Komponenten zur Unterstützung einer Microservice-Architektur.
Zalando setzt auf Fragmente (Teams), die von separaten Diensten ausgeliefert werden. Die Fragmente werden im Backend mit Template-Definitionen zusammengesetzt. Ein Layout-Service lädt den Inhalt aller Fragmente parallel aus einem Template.
Die einzelnen Fragmente sind einzelne AMD JavaScript Module, die Kommunikation zwischen den Fragmenten erfolgt über einen internen Event Bus. Es ist ein ähnlicher Ansatz wie Facebooks BigPipe, nur das dort die Komposition im Client stattfindet.
Beispiel:
<fragment src=”http://header.domain.com”></fragment>
<fragment src=”http://content.domain.com” primary></fragment>
<fragment src=”http://footer.domain.com” async></fragment>
An dieser Stelle möchte ich dir nun eine Gegenüberstellung der vorgestellten Micro-Frontend-Arten präsentieren, in der ich die einzelnen Ansätze anhand von elf Kriterien bewertet habe.
Die Kriterien sollen dazu dienen, einen Überblick über die spezifischen Vor- und Nachteile der einzelnen Micro-Frontend-Arten zu bekommen.
Kriterium | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
Mächtigkeit | ||||||
tech. unabhängig | ||||||
Kommunikation | ||||||
Routing | ||||||
Sharing | ||||||
Autonomie | ||||||
Client State | ||||||
Deployment | ||||||
Nachladen | ||||||
Lightweight | ||||||
UX |
Der Vergleichsmatrix ist zu entnehmen, dass es bei den verschiedenen Ansätzen immense Unterschiede gibt. Besonders auffällig ist, dass Multiple URL based SPAs in einigen Punkten besonders schlecht abschneiden, was der extremen Trennung der Applikationen geschuldet ist. Besonders positiv fällt die Bewertung der Framework Web Components und deren Self-Contained Variante aus, da sie sowohl mächtig als auch technisch unabhängiger ist.
Alle Varianten zeigen erhebliche Mängel im Bereich UX auf, was im Grunde auch zu einem gewissen Teil in ihrer Natur begründet ist.
Falls du mehr über eine einheitliche User Experience im Kontext von Micro-Frontends erfahren willst, wirf doch mal einen Blick in meinen vorangegangenen Blogartikel: "Mit Micro-Frontends Projektrisiken minimieren: So wird dein Frontend-Projekt erfolgreich".
Es gibt aktuell einfach noch keinen perfekten Weg, um Micro-Frontends mit allen wünschenswerten Vorteilen zu implementieren. An der einen oder anderen Stelle müssen aktuell noch Abstriche gemacht werden.
Die aktive Entwicklung und Community von Web Components lässt jedoch hoffen, dass sich dort in Zukunft noch viel tun wird. Wir sind gerade erst am Anfang von Web Components und sie sind meiner Meinung nach ein guter Schritt mittels Web Standards in Richtung technologische Unabhängigkeit zu gehen. Der Ansatz von Google mit Self-Contained Framework Web Components hört sich sehr interessant an und könnte auch kompatibel mit Web Frameworks der Zukunft sein.
Im Rahmen der von mir gegründeten Web-Engineering AG in Lünen, wo wir uns jeden Freitag mit den neuesten Trends aus dem Web beschäftigen, haben wir bei itemis einen Proof of Concept zum Thema Micro-Frontends im Kontext von Angular entwickelt.
Es handelt sich dabei um den Ansatz mit Framework Components. Dieser PoC veranschaulicht anhand eines minimalistischen Beispiels, wie man mit Angular eine Micro-Frontend-Architektur inklusive Composition Layer aufbauen kann.
Herunterladen kannst du dir dieses Beispielprojekt hier: