Microfrontends: Strategien für den Erfolg

Die richtige Microfrontend-Architektur kann Teams dabei helfen, effizient an komplexen Webanwendungen zu arbeiten und flexibel auf neue Anforderungen zu reagieren. Es gibt jedoch zahlreiche organisatorische und technische Ansätze, um Microfrontends umzusetzen, und die Wahl der richtigen Strategie ist entscheidend für ihren Erfolg. In diesem Artikel geben wir einen Überblick über die wichtigsten Ansätze. 

 

Was sind Microfrontends 

Microfrontends sind ein Architekturmuster für Webanwendungen. Sie zerlegen Frontend-Oberflächen in unabhängig entwickelte und bereitgestellte Teile, sodass Entwickler:innen diese isoliert entwickeln und aktualisieren können.  

Bei iteratec setzen wir auf individuelle Architekturen, die auf die Bedürfnisse unserer Kunden und deren Herausforderungen abgestimmt sind. So kann ein modularer Ansatz durch Microfrontends Vorteile bieten, die es ermöglichen, Entwicklungszeiten zu verkürzen und die Wartung und Erweiterung der Software um neue Features zu vereinfachen. 

Die Umsetzung von Microfrontends kann auf verschiedene Weisen erfolgen. Ein empfehlenswerter Artikel hierzu ist "Micro Frontends" von Cam Jackson, der sich mit einem Teil der grundlegenden technischen Ansätze auseinandersetzt. 

In diesem Artikel möchten wir über diese Grundlagen hinausgehen und sowohl tiefergehende als auch übergreifende Perspektiven bieten. Wir werden anhand der Unterschiede und Gemeinsamkeiten zwischen horizontalen und vertikalen Aufteilungen von Microfrontends die verschiedenen Integrationsmethoden, ihre technischen Rahmenbedingungen und deren spezifischen Vor- und Nachteile erläutern. 

 

Aufteilung von Microfrontends und Teams 

Microfrontends werden meist unter technischen Gesichtspunkten im Vergleich zu traditionell monolithisch konzipierten Web-Anwendungen betrachtet. Das Architekturmuster bietet aber auch große organisatorische Vorteile. Ein zentraler Punkt dabei ist, wie genau Microfrontends für eine Anwendung strukturiert und aufgeteilt werden – horizontal oder vertikal. 

split-all

Links: Horizontale Aufteilung – Mehrere Microfrontends werden dem Nutzer zeitgleich präsentiert 
Rechts: Vertikale Aufteilung – Nur jeweils ein Microfrontend wird dem Nutzer zur selben Zeit präsentiert 

 

Horizontale Aufteilung 

Bei der horizontalen Aufteilung werden dem Nutzer mehrere Microfrontends gleichzeitig präsentiert. Diese Aufteilung bietet sich besonders für Feature-Teams an: Microfrontends konzentrieren sich auf einzelne Features, welche parallel durch unabhängige Teams entwickelt werden.  

Teams werden bei der horizontalen Aufteilung nach Fachlichkeit und nicht nach technischen Gesichtspunkten gruppiert. Ein Microfrontend-Team ist hiermit in der Regel auch für die API-Entwicklung verantwortlich. Im Gegensatz zu Component-Teams gibt es bei Feature-Teams kein dediziertes „Backend“-Team. In einem Ende-zu-Ende-Ansatz wird der Feature-Lifecycle in den Mittelpunkt gerückt und das Team besitzt volle Verantwortung für alle Aspekte eines Features. Dies ist oft vorteilhaft für die User-Experience, da das Team ein tieferes Verständnis für die gesamte Funktionsweise des Features entwickeln kann und in der Lage ist, schnell auf Benutzerfeedback zu reagieren. 

Ein weiterer Vorteil der horizontalen Aufteilung liegt in der Wiederverwendbarkeit einzelner Microfrontends, wie z.B. Authentifizierung, Kopfzeilen, Fußzeilen oder gemeinsam genutzte Layout-Komponenten. In einem E-Commerce-Store kann z.B. die Such-Funktion als Microfrontend bereitgestellt und an verschiedenen Stellen innerhalb der Hauptanwendung eingebunden werden, was organisatorische Probleme wie Doppelarbeit reduziert. 

 

Vertikale Aufteilung 

Bei der vertikalen Aufteilung wird zu jedem Zeitpunkt nur ein Microfrontend dem Nutzer präsentiert, wobei das Routing zwischen diesen über die URL geschieht. Diese Aufteilung orientiert sich an der klassischen Architektur für Web-Anwendungen. Die einzelnen Microfrontends können mittels der jeweils geeigneten Architektur und Technologie relativ unabhängig als eigenständige Web-Applikationen entwickelt werden. 
 
Im Gegensatz zur horizontalen Aufteilung kann die vertikale Aufteilung nicht nur mit Feature-Teams, sondern auch sinnvoll mit Component-Teams umgesetzt werden. Bei diesen Teams kann es pro Feature verteilte Verantwortliche geben. Beispielsweise kann ein Component-Team für die API verantwortlich sein, während ein anderes Team das Frontend entwickelt. 
 
In einem E-Commerce-Store kann z.B. die Benutzerverwaltung als vertikal aufgeteiltes Microfrontend mittels zweier Component-Teams realisiert werden. Die Benutzerverwaltung wird nicht parallel zu anderen Features des Stores angezeigt und muss explizit vom Nutzer geöffnet werden (im Gegensatz zu der vorhin genannten Suche bei horizontaler Verteilung). Die Verwaltung wird von zwei Component-Teams entwickelt – ein Team für das Frontend sowie ein weiteres für die entsprechende API. Natürlich ist auch die Entwicklung durch nur ein Feature-Team mit Verantwortung für das Frontend und das Backend möglich. 

Für Querschnittsthemen in Implementierung und Design muss die vertikale Aufteilung individuelle Lösungen finden, beispielsweise über bereitgestellte Libraries und klar definierte User Experience Guidelines. Dies gilt auch für die horizontale Aufteilung, allerdings hat diese hier oft einen Vorteil, da sie insgesamt stärker auf Wiederverwendbarkeit ausgerichtet ist. 

 

Die richtige Entscheidung treffen 

Die Entscheidung zwischen vertikaler und horizontaler Aufteilung ist nicht immer eindeutig und muss gut überlegt sein. Ebenso wenig lässt sich eine generelle Empfehlung für Feature- vs. Component-Teams aussprechen. In der Praxis trifft man häufig auf einen Kompromiss zwischen den Ansätzen und selten auf durchgehend konsistente Lösungen. 

Für ein tiefergehendes Verständnis, insbesondere welche Team-Topologie sich für welche Aufteilung der Microfrontends eignet, bietet sich “Building Micro-Frontends von Luca Mezzalira als weiterführende Information an. Hier wird auch gut erklärt, wie sich Konzepte aus dem Domain Driven Design mit Microfrontends realisieren lassen. 

Obwohl es viele Faktoren zu berücksichtigen gibt und eine allgemeine Empfehlung schwierig ist, zeigt die Erfahrung, dass sich die horizontale Aufteilung von Microfrontends durch Feature-Teams besonders bei Projekten in der Wachstumsphase immer stärker durchsetzt. Zudem ist die horizontale Aufteilung aus technischer Perspektive interessanter als die vertikale Aufteilung, da letztere wesentlich mehr auf traditionellere Webentwicklungstechniken wie Single-Page-Applications aufbaut. 

Daher wollen wir uns im Folgenden bewusst mehr mit der horizontalen Aufteilung, den technischen Rahmenbedingungen und Herausforderungen auseinandersetzen. 

 

Ansätze für horizontale Aufteilung 

Eine horizontale Aufteilung von Microfrontends bedingt, dass unabhängig entwickelte Frontends zusammengeführt werden. Dies lässt sich durch drei grundlegende Ansätze realisieren: 

  • Buildtime Integration 
  • Server-seitige Integration 
  • Client-seitige Integration 

Die Ansätze unterscheiden sich vor allem darin, zu welchem Zeitpunkt die Microfrontends in die Gesamtanwendung eingebettet werden. Die Ansätze vereint, dass sie aus Nutzersicht eine nahtlose und einheitliche Webanwendung ermöglichen. Wir vergleichen die Ansätze im Folgenden und geben erste Indikatoren, wann welcher Ansatz passen könnte. Dabei interessieren uns unter anderem folgende Messwerte: 

  • Time to First byte (TTFB): Zeit, die der Browser benötigt, um das erste Byte der Antwort vom Server zu erhalten. Es ist ein Indikator für die Server-Reaktionszeit 
  • Largest Contentful Paint (LCP): Zeit, bis das größte sichtbare Element im Client/Browser vollständig geladen ist. Es gibt einen guten Hinweis darauf, wann der Hauptinhalt einer Seite für den Nutzer sichtbar wird. 

Diese beiden Messwerte sind interessant, weil sie die Ladegeschwindigkeit beeinflussen. Eine schnellere Ladezeit sorgt für eine bessere Benutzererfahrung, da Nutzer weniger warten müssen und schneller mit der Seite interagieren können. 

 

Buildtime Integration  

Bei der Buildtime Integration werden die Microfrontends bereits während des Build-Prozesses in die Anwendung eingebettet. Aus Sicht des Browsers existieren keine separaten Microfrontends, da alle notwendigen Integrationsschritte bereits abgeschlossen sind. Die Microfrontends werden als Abhängigkeiten der Hauptanwendung behandelt und unterscheiden sich nicht wesentlich von anderen externen Abhängigkeiten, wie etwa Komponentenbibliotheken. 

build-time

Abbildung 1: Die Microfrontends werden als Buildtime-Module bereits zur Entwicklungszeit von der Hauptanwendung eingebunden und während des Build-Prozesses durch einen Bundler fest zu einer Anwendung verdrahtet. 

 

In der Praxis werden die Microfrontends oft als JavaScript-Module bereitgestellt, die zusammen mit dem restlichen Anwendungscode durch einen Bundler wie Webpack oder Vite verpackt werden. Diese werden als Buildtime-Module bezeichnet, da sie Teil des gebündelten Endprodukts sind. 

Spezielle Techniken oder Bibliotheken zur Laufzeit sind daher auch nicht notwendig. Es gibt jedoch unterstützende Tools, die den Build-Prozess erleichtern können, wie etwa eine private NPM-Registry oder Dienste wie bit.dev, die das Verwalten von Abhängigkeiten für Entwicklungsteams vereinfachen. 
 
Die Buildtime-Integration ist besonders vorteilhaft für Projekte, bei denen die Zusammensetzung der Microfrontends nicht dynamisch ist und ein hoher Wert auf Performance gelegt wird. Für die Time To First Byte kann dieser Ansatz den bestmöglichen Wert liefern, da der Server nur noch das fertige Bundle ausliefern muss. Allerdings muss darauf geachtet werden, dass die Bundle-Size der Anwendung insgesamt klein gehalten wird - andernfalls kann der Largest Contentful Paint erheblich darunter leiden. Gerade bei größeren Anwendungen ist dies oft nur zu einem gewissen Grad beeinflussbar. In diesem Fall bieten sich alternative Integrationsansätze über den Server oder den Client an. 

 

Server-seitige Integration 

Die Server-seitige Integration geht einen Schritt weiter als die Buildtime-Integration, indem sie die Zusammensetzung der Anwendung bis zum Zeitpunkt der Serveranfrage zurückhält. Hierbei werden verschiedene Middleware-Lösungen eingesetzt, die als Template-Engines fungieren, um die Microfrontends zur Laufzeit in eine Hauptanwendung zu integrieren. Wird die Integration auf der Ebene des Content Delivery Networks (CDN) durchgeführt, spricht man oft auch von Edge-side Integration. Der Client bleibt von der Zusammensetzung unberührt. 

server-side

Abbildung 2: Bei der Server-seitigen Integration werden die Microfrontends dem Server zur Verfügung gestellt. Dieser fügt diese mittels einer Template-Engine zu einer Hauptanwendung zusammen. Der Client ist davon unberührt und sieht nur eine Anwendung. 

 

Dieser Ansatz belastet den Server stärker als die Buildtime-Integration und erhöht die Time to First Byte (TTFB). Der Einsatz einer leistungsfähigen Middleware bzw. Template-Engine, die die Anwendung und die angeforderten Microfrontends effizient rendert, ist daher empfehlenswert. 

Traditionelle Methoden wie Server-Side Includes (SSI) oder Edge-Side Includes (ESI) sind trotz ihres Alters stabile Standards, die von vielen Servern und CDNs unterstützt werden, auch wenn ihre Implementierung je nach Anbieter/Vendor variieren kann. Allerdings sind diese Techniken oft weniger beliebt für neue Projekte, da sie ein nicht mehr ideales Nutzererlebnis für Entwickler:innen bieten. Moderne Alternativen wie Podium, Isomorphic Layout Composer (ILC), Piral und Tailor bieten fortschrittlichere aber weniger verbreitete Lösungen. 

Im Vergleich zur Buildtime Integration ermöglicht die Server-seitige Integration eine höhere Flexibilität und Skalierbarkeit, da Microfrontends unabhängig voneinander ausgeliefert und aktualisiert werden können. 

Für reine server-seitige Integrationen müssen die anzuzeigenden Microfrontends bereits im Request an den Server enthalten sein, damit dieser weiß was zu rendern ist. Wenn zu einem neuen Microfrontend navigiert werden soll, ist eine erneute Anfrage erforderlich. Dabei liefert der Server die komplette Anwendung erneut aus, einschließlich jener Microfrontends, die unverändert bleiben. 

Dieser Ansatz ist daher für interaktive Anwendungen weniger geeignet, da häufige Serveranfragen die Benutzererfahrung beeinträchtigen können. In der Praxis wird daher häufig ein kombinierter Ansatz mit der Client-seitigen Integration verwendet. 

 

Client-seitige Integration 

Bei der Client-seitigen Integration werden die Microfrontends einzeln im Browser geladen und somit zum letztmöglichen Zeitpunkt in die Anwendung integriert. Dieser Ansatz bietet nochmal höhere Flexibilität als die Server-seitige Integration und ermöglicht eine verbesserte Performance beim Routing zwischen Microfrontends, da nur die aktuell benötigten Module dynamisch vom Server geladen werden müssen. 

client-side

Abbildung 3: Für die Client-seitige Integration stellt der Server die einzelnen Microfrontends zur Verfügung. Diese werden von Client abgerufen und in die Hauptanwendung eingebettet. 

 

Da Client-seitig für die Integration erst Javascript-Code ausgeführt werden muss, wird der LCP beim ersten Seitenaufruf potenziell später erreicht als bei der Server-seitigen Integration.  

In der Praxis wird daher häufig ein kombinierter Ansatz mit der Server-seitigen Integration verwendet. Hierbei rendert der Server eine statische Seite, die alle Microfrontends enthält, und sendet diese an den Client. Auf dem Client wird dann JavaScript ausgeführt, um interaktive Module mittels Hydration zu aktivieren. Hydration bezieht sich auf den Prozess, bei dem eine statisch gerenderte Seite durch das Ausführen von JavaScript in eine voll interaktive Seite umgewandelt wird. Diese Technik ermöglicht es, die Nutzererfahrung zu beschleunigen, indem der initial sichtbare Inhalt schnell dargestellt wird, während interaktive Funktionen nachgeladen und aktiviert werden, sobald das JavaScript verfügbar und ausgeführt ist. 

Zur Realisierung der Runtime Integration gibt es vor allem zwei technische Ansätze: 

  • Client-seitige Integration via iFrames 
  • Client-seitige Integration via DOM-Manipulation
 

Client-seitige Integration via iFrames 

iFrames stellen einen technisch einfachen Ansatz zur Integration von Microfrontends dar. Sie funktionieren, indem sie eigenständige Webanwendungen innerhalb des gleichen Browserfensters als getrennte Einheiten laden. iFrames bieten eine starke Isolation zwischen den verschiedenen Microfrontends und verfügen über zahlreiche integrierte Sicherheitsfunktionen. 

Die Einbettung von iFrames erfordert in der Regel keine speziellen Frameworks. Entwickler:innen können auf Standard-HTML- und JavaScript-Techniken zurückgreifen, um iFrames in ihre Anwendungen zu integrieren. Allerdings haben iFrames Nachteile, die ihre Einsatzmöglichkeiten stark limitieren können: 

  • Layoutbeschränkungen: iFrames unterstützen kein responsives Verhalten bezüglich der automatischen Anpassung ihrer Höhe, was die Erstellung responsiver Layouts erschwert. 
  • Performance: Das Verwalten mehrerer iFrames kann für Browser ressourcenintensiv sein. Intensiver Einsatz von iFrames kann daher die Leistung einer Anwendung beeinträchtigen und zu merklichen Einbußen bei der Nutzererfahrung führen. 
  • Barrierefreiheit und SEO: iFrames können die Barrierefreiheit und die Suchmaschinenoptimierung einer Seite negativ beeinflussen. Sie unterbrechen die semantische Struktur einer Seite, und Suchmaschinen-Crawler indizieren die Inhalte von iFrames oft als separate Seiten, wodurch der Kontext der Einbettung verloren geht. 

Für viele Anwendungen ist die Nutzung von iFrames trotzdem ein valider und empfohlener Ansatz. Gerade bei internen Unternehmensanwendungen, die eingeschränkten Layout und SEO-Anforderungen unterliegen, sind iFrames als Integrationsmethode für Microfrontends sehr beliebt. Auch darüber hinaus erfreuen sich iFrames Beliebtheit: Beispielsweise nutzt YouTube iFrames, um Videos auf verschiedenen Websites einzubetten.  

 

Client-seitige Integration via DOM-Manipulation 

Im Gegensatz zu iFrames löst die Client-seitige Integration durch DOM-Manipulation viele der genannten Probleme. Das DOM (Document Object Model) ist die interne Struktur einer Website im Browser und ermöglicht über eine JavaScript-API die Manipulation in Echtzeit. Diese API wird genutzt, um Microfrontends erst im letzten Moment in die Website zu integrieren. 

Anders als bei der Buildtime-Integration, die statische Buildtime-Module verwendet, werden Microfrontends hier als dynamisch ladbare In-Browser JavaScript-Module bereitgestellt. Jedes Microfrontend agiert als ein eigenständiger Knoten im DOM, der zur Laufzeit einem bestehenden Element der Hauptanwendung hinzugefügt wird. 

dom-manipulation

Abbildung 4: Die Hauptanwendung wird vom Client inklusive JavaScript Code geladen. Letzterer lädt die Microfrontends zur Laufzeit nach und fügt diese an den vorgesehenen Stellen im DOM ein. 

 

Im Vergleich zur iFrame-Methode, bei der spezielle iFrame-Elemente benötigt werden, kann bei der DOM-Manipulation praktisch jedes DOM-Element als Anker verwendet werden – häufig geschieht dies mittels div-Elementen. Zudem müssen Microfrontends bei dieser Methode nicht als eigenständige Webanwendungen konzipiert sein. 

Es gibt einige Libraries und Technologien, welche zur Umsetzung dieses Ansatzes beliebt sind - unter anderem Single-SPA, Module Federation und Import Maps. Als weiterführende Lektüre für technische Aspekte ist Micro Frontends in Action von Michael Geers sehr empfehlenswert. 

 

Fazit 

In diesem Artikel haben wir einen umfassenden Überblick über Microfrontends als Architekturmuster gegeben. Dabei haben wir verschiedene Ansätze mit ihren Vor- und Nachteilen verglichen, die je nach Kontext und Anwendungsfall unterschiedlich gewichtet werden müssen. Darüber hinaus gibt es jedoch noch zahlreiche weitere Herausforderungen, die von allen Ansätzen geteilt werden. 

Obwohl einzelne Teams ihre Microfrontends unabhängig entwickeln, muss letztlich jemand die Verantwortung für Integrationstests übernehmen, um sicherzustellen, dass das Zusammenspiel aller Microfrontends reibungslos funktioniert. Die Sicherstellung einer einheitlichen Benutzererfahrung über alle Microfrontends hinweg ist ebenso wichtig. 

Auf technischer Ebene ist es essenziell, Strategien für den Fall zu entwickeln, dass einzelne Microfrontends nicht erreichbar sind. Zusätzlich muss die Kommunikation zwischen den Microfrontends sowie zahlreiche Sicherheitsaspekte sorgfältig geplant und umgesetzt werden. 

Microfrontends bieten enormes Potenzial, um Anwendungen modular und flexibel zu gestalten. Allerdings muss man sich der vielfältigen Herausforderungen und der damit verbundenen Komplexität bewusst sein. Bei iteratec verstehen wir diese Herausforderungen und unterstützen Sie gerne mit unserer umfangreichen Erfahrung und Projektexpertise. 

 

 

Philipp_SeßlerPhilipp Seßler - Philipp Seßler ist Senior Software Architekt bei iteratec. Er legt großen Wert auf die enge Zusammenarbeit mit Kunden, um gemeinsam passgenaue Lösungen für deren Herausforderungen zu entwickeln. Dabei hat er unter anderem Carsharing-Systeme, digitale Gesundheitsplattformen und innovative Lösungen für Startups realisiert. Philipp ist spezialisiert auf Architekturberatung und Full-Stack-Entwicklung, wobei er eine besondere Leidenschaft für Java, Go und das Web-Ökosystem pflegt.

 

 

Tags: Individualsoftwareentwicklung, Digital Business Innovation

Verwandte Artikel

Many leaders have high expectations when starting an agile transformation. Just imitating what, e.g. the Scrum Guide describes,...

Mehr erfahren

Topics: Individualsoftwareentwicklung, Digital Business Innovation

Agile has exceeded the boundaries of it’s original domain, software development. Today many companies claim to do Agile. Projects...

Mehr erfahren

Topics: Individualsoftwareentwicklung, Digital Business Innovation

When people feel they have no influence on the organizations goals, they become disconnected from the products they build and...

Mehr erfahren

Topics: Individualsoftwareentwicklung, Digital Business Innovation