Podcast

Microfrontends

Unabhängige Teams im Frontend

Microservices sind in aller Munde. Aber was passiert im Frontend? Gibt es dort ähnliche Überlegungen? In dieser Folge stellen sich Franziska Dessart und Lucas Dohmen den Fragen von Stefan Tilkov. Die beiden stellen zwei sehr unterschiedliche Ansätze vor, die unter dem Namen Microfrontends bekannt sind, und erläutern Vor- und Nachteile.
Weitere Episoden anhören

Shownotes & Links

Transkript

Transkript ausklappen / einklappen

Stefan Tilkov: Hallo und herzlich Willkommen zu einer neuen Episode des INNOQ–Podcasts. Heute zum Thema Microfrontends. Weil das ja ein komplexes Thema ist, zu dem es viele Kleinteile gibt, sind wir heute passenderweise zu dritt. Ich habe als Kollegen dabei: Franzi. Hallo Franzi!

Franziska Dessart: Hallo Stefan!

Stefan Tilkov: Und Lucas. Hi Lucas!

Lucas Dohmen: Hallo!

Stefan Tilkov: Sagt doch ganz kurz, wer ihr seid. Franzi, fang du doch an.

Franziska Dessart: Ich bin Franziska Dessart. Ich arbeite bei INNOQ als Senior Consultant und meistens irgendwie im Webumfeld.

Stefan Tilkov: Alles klar. Und Lucas, dich kennen die meisten unserer Hörer, aber stell dich trotzdem kurz vor.

Lucas Dohmen: Ja, ich bin Lucas. Ich bin auch Senior Consultant bei INNOQ und ich beschäftige mich auch vor allem mit dem Web in allen möglichen Formen: Frontend, Backend, Architektur und so weiter.

Stefan Tilkov: Alles klar. Und unser Thema heute sind Microfrontends. Absolut hippes Hashtag–kompatibel. Und deswegen fangen wir direkt einmal an und klären erstmal, worum es denn geht, womit sich Microfrontends überhaupt beschäftigen und welches Problem sie lösen wollen. Franzi, willst du anfangen?

Franziska Dessart: Ja. Im Großen und Ganzen würde ich sagen: Microfrontends sind Frontends für Systeme, die aus Einzelsystemen bestehen, und bei denen ich dann nicht einen Frontend–Monolithen davor setzen möchte, sondern meine Frontends aus Einzelteilen zusammenbauen möchte und die dann wieder miteinander integriere.

Stefan Tilkov: Was wäre denn schlecht daran, einen Frontend–Monolithen zu haben?

Lucas Dohmen: Ja, wenn man sich sowieso dafür entscheidet, sein Backend in verschiedene Teile zu zerteilen, gibt es ja auch gute Gründe, dasselbe beim Frontend zu tun. Also wenn man sagt, unser Backend ist so komplex, dass wir daraus nicht ein riesiges Monster bauen wollen, das wir auch nur auf einen Schlag deployen können und so weiter, gelten dieselben Argumente im Prinzip fürs Frontend auch. Denn Frontends sind nun einmal komplexer als man erstmal denkt. Da gibt es ja auch viel, was da passiert, und auch das wollen wir nicht als ein riesiges Deployment–Artefakt haben, das man auf einen Schlag deployen muss.

Stefan Tilkov: Okay, wenn wir mal davon ausgehen, dass wir da ähnliche Argumentationen haben wie im Backend, gilt es dann auch, dass manchmal ein monolithisches Frontend auch in Ordnung sein kann, genauso wie manchmal ein monolithisches Backend in Ordnung sein kann?

Lucas Dohmen: Ich denke schon. Grundsätzlich gibt es immer einen guten Anwendungsfall für einen Monolithen im Frontend und im Backend. Ganz einfach wäre ja der Fall, wir haben eine Monolithen als Backend, dann haben wir wahrscheinlich auch einen Monolithen als Frontend. Die Architektur gibt es auf jeden Fall. Und ich denke, es könnte auch durchaus sein, wenn man wirklich ein sehr, sehr einfaches Frontend hat, das aber mit sehr, sehr viel Backend–Logik sprechen muss, könnte man sich auch durchaus denken, dass man auch ein Frontend bauen könnte, das ein Monolith ist. Obwohl ich da… Das weiß ich nicht, da würde mir jetzt kein richtiger Fall einfallen, weil es immer noch häufig so ist, dass wir gerade auch zwischen Frontend und Backend einen Koordinationsaufwand haben. Wenn wir jetzt einen Frontend–Monolithen haben und wir wollen ein weiteres Ding hinzufügen zu unserem Frontend und das benötigt garantiert irgendetwas im Backend, das heißt, wir haben schon wieder so einen Abstimmungs–Overhead zwischen dem Frontend–Monolithen–Team und mindestens einem Microservices–Backend–Team und das klingt für mich schon wieder nach einer Struktur, die nicht so optimal ist.

Stefan Tilkov: Stimmst du dem zu, Franzi?

Franziska Dessart: Ich denke, ein valider Use Case von Monolithen – aber da würde ich das jetzt so sehen, dass quasi das Frontend und das Backend aus demselben Monolithen kommen – ist einfach, wenn das System an sich ganz klein ist, und überschaubar, und es sich gar nicht – weder im Frontend noch im Backend – rentiert, das in mehrere Systeme zu schneiden.

Lucas Dohmen: Genau. Aber den Fall, dass man wirklich ein Frontend–Monolithen und ein Microservices–Backend hat, den sehe ich nicht so wirklich, dass das Sinn ergibt.

Franziska Dessart: Nein, das nicht, nein.

Stefan Tilkov: Das müsst ihr noch mal erklären. Ich glaube, das, was ihr gerade beschrieben habt: Ein Microservice–Backend, also ein Backend, bei dem man schöne, kleine Services gebastelt hat, die wiederverwendbar sind in verschiedenen Kontexten und die vielleicht in verschiedenen Programmiersprachen geschrieben sind, ihre eigenen lokalen technischen Entscheidungen treffen und vielleicht ihre eigene Persistenz haben und so weiter und so fort, mit einem monolithischen – wobei man das Wort da nicht benutzen würde – mit einem einheitlichen, einzigen Frontend davor, zum Beispiel einer single–page app, einer modernen. Das ist, glaube ich, eine extrem übliche Architektur. Wenn ihr jetzt sagt, ihr seht da gar keine Vorteile, müsst ihr da wahrscheinlich ein bisschen näher erläutern, warum ihr da keine Vorteile seht bzw. was genau ihr für Nachteile seht.

Lucas Dohmen: Ja. Also, für mich ist da der Hauptnachteil an dieser Architektur, diese Einteilung zwischen einem Team, das Frontend macht, und einem oder mehreren Teams, die Backends machen, ist auf jeden Fall schon ein Punkt, der mir nicht gefällt. Denn das bedeutet, dass für fast alle Änderungen, die wir machen, mehrere Teams involviert sein müssen. Mein Ziel bei einer Architektur, die so komplex ist, dass wir mehrere Teams haben müssen, wäre, dass jedes Team von den anderen unabhängig arbeiten kann. Das heißt, wenn jemand sagt, wir brauchen jetzt ein neues Feld für unser Registrierungsformular, dann sollte dieses Requirement von einem Team gelöst werden und nicht von einem Frontend–Team, das dann mit einem Backend–Team reden muss, damit es das Feld im Backend hinzufügt, und dann vielleicht noch mit einem Datenbank-Team, das es in der Datenbank hinzufügt.

Sondern ich würde das halt gerne sehen, dass das ein Team ist, das sich quasi von Front– bis Backend mit einem fachlichen Teil der Anwendung beschäftigt und damit auch solche Änderungen autonom durchführen kann. Denn nur dann haben wir keine extrem starken Abhängigkeiten zwischen den Teams, die erfordern, dass jetzt erst einmal das „Team A Microservice“ ein Deployment durchführt von ihrem Microservice und dann muss das Team vom Frontend auch noch mal ein Deployment durchführen. Solange muss es aber irgendwie mit beiden Versionen sprechen können usw. Das sind Punkte, bei denen meiner Meinung nach einfach sehr viel Reibungsverlust ist, dadurch dass wir sehr viel Koordination zwischen Teams machen müssen. Das heißt, eigentlich fast jeder Change erfordert, dass das Frontend–Team irgendetwas tut und ein Microservice–Team. Und das sehe ich einfach nicht als eine gute Teamstruktur.

Franziska Dessart: Ja, dem würde ich zustimmen. Also Ziel sollte auf jeden Fall sein, dass möglichst zwischen den Teams so wenig wie möglich miteinander gesprochen werden muss und so wenig wie möglich koordiniert werden muss.

Stefan Tilkov: Okay, gut. Also das heißt, das Ziel von Microfrontends ist es, eine Modularisierung des Frontends hinzubekommen, die es erlaubt, die Dinge anders zu bündeln. Die es erlaubt, vielleicht Frontend–Teile mit Backend–Teilen zusammen zu bündeln, die fachlich auch zusammen gehören. Und generell im Frontend einfach eine ähnliche Modularisierung hinzubekommen, wie man sie im Backend mit Microservices auch erreicht. Korrekt?

Lucas Dohmen: Genau.

Franziska Dessart: Hmh [zustimmend].

Stefan Tilkov: Okay. Dann lasst uns doch mal darüber sprechen, wie man das erreichen könnte. Zunächst einmal, unser Fokus sind Webanwendungen, über die wir hier sprechen. Nicht mobile Anwendungen oder Desktop–Anwendungen, sondern Webanwendungen. Auf die anderen können wir vielleicht am Ende noch einmal eingehen, aber lasst uns uns erst einmal darauf konzentrieren. Was für Lösungsansätze seht ihr denn, um die Microfrontend–Idee umzusetzen?

Lucas Dohmen: Also ein Lösungsansatz wäre, jedes der Teams baut eine server–seitig gerenderte Anwendung und die Anwendungen sind fachlich geschnitten. Also, wir haben ein Team, das sich jetzt – weiß ich nicht – mit dem Buchungsprozess beschäftigt, und eins, das sich mit den Artikelseiten beschäftigt, beispielsweise. Und wenn die beiden sich miteinander integrieren wollen, dann ist das erste Werkzeug, dass sie einfach Links zwischen diesen beiden Anwendungen bauen. Das heißt, der User wird einfach von der einen Anwendung zu der anderen Anwendung geschickt. Das würde jetzt das Format dieses Podcasts sprengen, aber da muss man dann halt über solche Sachen reden wie gesharete Styles und Styleguides und so weiter, das klammere ich jetzt mal aus, dass der User nicht bemerkt, dass er da jetzt zwischen zwei Anwendungen hin und her gewechselt ist. Aber grundsätzlich wechselt er einfach zwischen den Anwendungen und bekommt das gar nicht mit. Und genauso könnte man da auch Dinge benutzen wie eine Transklusion. Da haben wir auch eine ganze Folge vom INNOQ–Podcast zu gemacht mit Franzi, in dem verschiedene Ansätze vorgestellt werden, wie man Inhalte von dem einen Backend in dem anderen darstellen kann, und zwar indem man einfach nur HTML–Inhalte einbettet in seine Antwort mit irgendeiner Möglichkeit.

Stefan Tilkov: Ohne den gesamten Transklusions–Podcast noch einmal zu rekapitulieren, könntest du, Franzi kurz erklären, wie das dann funktioniert mit der Transklusion? Passiert das client–seitig, server–seitig oder beides?

Franziska Dessart: Das kommt darauf an. Das kann man sich aussuchen. Also da gibt es ganz viele Stellen, an denen man das machen kann. Auf verschiedenen Servern könnte man es server–seitig machen. Ich könnte es irgendwie bei mir zu Hause in meinem Origin–Server, also dem eigentlichen Application–Server, machen, ich kann so ein extra System wie Tailor aufsetzen, zum Beispiel. Ich kann meinen Webserver nehmen, mein Cashing–Proxy oder auch mein CDN oder ich kann es auch client–seitig im Browser machen.

Stefan Tilkov: Okay. Das klingt jetzt ziemlich genau wie das, was wir sonst auch erzählen, wenn wir oder andere von Self–contained Systems sprechen. Sind Self–contained Systems und Microfrontends jetzt das Gleiche oder nur kompatibel oder ähnlich, aus eurer Sicht?

Franziska Dessart: Also, vielleicht nicht eine genaue Schnittmenge, aber zumindest eine Untermenge, aber vielleicht noch eine speziellere. Also, ich glaube, Microfrontends ist ein Begriff, der ganz viele Varianten zusammenfasst, also jeder interpretiert den ein bisschen anders. Und die SCS–Variante mit ROCA und Transklusion, das wäre jetzt die sehr… Also, wenn ich so ein Spektrum aufziehen will, von dem einen zum anderen Ende, dann wäre das sehr weit an dem Ende zu server–seitig gerendert.

Stefan Tilkov: Okay. Was wäre denn die nächste Stufe?

Franziska Dessart: Da bin ich mir jetzt mit der Reihenfolge nicht ganz sicher. Vielleicht kann Lucas da mal aushelfen, aber ich würde auf jeden Fall sagen, am anderen Ende sitzt etwas sehr oder ausschließlich client–seitig gerendertes.

Stefan Tilkov: Wie muss ich mir das vorstellen? Ausschließlich client–seitig gerendertes, das hört sich an wie eine single–page app, Lucas? Ist es das, worum es da geht?

Lucas Dohmen: Genau. Also das wäre jetzt wirklich das… Das komplette Gegenteil wäre, wir haben mehrere Single–Page–Applikationen, beispielsweise jetzt eine React–App oder eine Angular–App und davon haben wir mehrere und die wollen wir miteinander integrieren. Und da haben wir jetzt so ein bisschen die Schwierigkeit, dass der traditionelle Weg, wie die funktionieren, ja ist, dass die sowohl client–seitig Kontrolle über das Routing übernehmen als auch über den State. Und das heißt, jeder möchte so ein bisschen den State verwalten für sich selbst. Und wenn die jetzt miteinander reden wollen, dann müssen wir uns eine Lösung einfallen lassen, wie die miteinander kommunizieren können, also Nachrichten miteinander austauschen können. Und da haben wir jetzt – dazu können wir den Blogpost verlinken – einen Ansatz gefunden, wo quasi client–seitig ein Message–Bus aufgebaut wird, in den dann die verschiedenen Single–Page–Applikationen Nachrichten hineinschreiben und herauslesen können und so miteinander kommunizieren können. Und weiterhin kann halt jede von den Anwendungen den eigenen State unabhängig von den anderen verwalten, aber wenn sie miteinander reden wollen, dann müssen sie diesen Message–Bus benutzen. Das Problem daran ist noch ein bisschen, dass man sich trotzdem darüber einigen muss, wer von diesen Anwendungen jetzt die Kontrolle über die URL übernimmt, darum kommen wir nicht herum, darin können ja nicht einfach alle herum schreiben, das würde vielleicht zu Chaos führen. Das heißt, wir müssen schon eine primäre Anwendung irgendwie festlegen, die dieses Rahmenwerk bildet. Und dann können diese einzelnen Anwendungen dann miteinander über so einen Message–Bus “sprechen”.

Stefan Tilkov: Jetzt steckt in dem, was du gerade gesagt hast, aber eine Annahme, nämlich dass ich unterschiedliche Anwendungen oder Komponenten mit möglicherweise unterschiedlichen Frameworks bauen möchte. Das will ich ja vielleicht gar nicht. Vielleicht bin ich ja der festen Überzeugung, dass – jetzt kann jeder würfeln oder einsetzen, was ihm oder ihr gerade am besten gefällt – dass diese Woche Vue oder React oder Angular oder Ember oder was auch immer das Coolste von allen ist und ich sowieso immer alles nur mit – von mir aus – Ember machen würde. Ich kenne jetzt Ember nicht genau, aber ich vermute mal, die haben bestimmt innen drin auch so etwas wie ein Komponentenkonzept. Dann könnte ich ja auch einfach das Komponentenmodell benutzen, das sozusagen im Framework meiner Wahl drin ist, oder? Wäre das dann auch Microfrontends?

Lucas Dohmen: Das könnte ich tun, das wäre ein Ansatz, den ich verfolgen kann. Das Problem daran ist, dass das nicht funktioniert, weil wir mit der Änderung umgehen können müssen, dass eine neue Version von unserem Framework herauskommt. Also gehen wir jetzt einmal davon aus, wir haben uns für Ember entschieden und es kommt jetzt Ember Version 2.4.3 heraus und wir haben bisher 2.3.0 und dafür müssen wir ein paar Code Changes durchführen. Jetzt müssten also alle Komponenten, die wir gebaut haben und alle Anwendungen mit einem Schritt gleichzeitig die neue Framework–Version einsetzen, denn sonst sind wir in demselben Szenario, das wir hätten, wenn wir zum Beispiel eine React– und eine Angular–App hätten: Wir haben zwei unterschiedliche Frameworks, die wir laden und die nicht miteinander kompatibel sind. Denn Ember 2.4 und Ember 2.0 sind genauso inkompatibel miteinander wie Angular und Ember. Das heißt, das müssen wir einfach von Anfang an vorsehen. Selbst wenn wir die Entscheidung treffen, wir bleiben für immer bei Ember. Das rettet uns davor nicht und und wir müssen trotzdem ein Kommunikationskonzept vorsehen, durch das die miteinander reden können.

Oder wir treffen die Entscheidung, dass wir wirklich bei Updates alles gleichzeitig updaten müssen. Dann haben wir aber wieder die Situation, in der wir eigentlich nicht sein wollen, nämlich dass wirklich alles gleichzeitig geupdatet wird. Das heißt, wir haben einen synchronisierten Aufwand zwischen allen Teams. Und wenn wir uns jetzt vorstellen, dass das vielleicht ein größeres Update ist, dann wird das vielleicht auch nie passieren. Was ja zum Beispiel bei vielen Angular–Apps passiert ist, bei dem Update von 1 auf 2, da sind sehr viele nicht mitgegangen, weil sie es einfach nicht geschafft haben, auf einen Schlag irgendwie dieses Riesen–Update zu machen. Und deswegen muss man, meiner Meinung nach, diesen Aspekt vorsehen, selbst wenn man sagt, wir machen grundsätzlich alles in React.

Stefan Tilkov: Das ist irgendwie interessant, das ist wirklich die hundertprozentig exakt gleiche Diskussion, die wir im Backend ja auch führen. Wo Leute sagen, wir brauchen dieses Polyglott–Feature nicht, wir machen sowieso nur Java. Und da kann man genau die gleiche Diskussion führen: Es mag ja sein, dass alle nur Java machen oder C# oder was auch immer, aber man will eben vielleicht auch nicht immer überall alles im selben Takt auf die nächste Java oder Node oder C#–Version hochziehen. Genau das Gleiche gilt im Frontend natürlich auch.

Lucas Dohmen: Genau.

Stefan Tilkov: Wenn man denn entschieden hat, dass es groß genug ist, dass man es modularisieren will. Okay, das habe ich verstanden.

Franziska Dessart: Ja, nur der Unterschied ist, dass man im Backend einfacher unterschiedliche Deployments hinbekommt und im Browser steckt halt am Ende einfach alles zusammen.

Stefan Tilkov: Was sind denn das für typische Probleme, die man hat, wenn man zwei verschiedene Versionen oder zwei verschiedene Frameworks gleichzeitig in einer Page benutzt?

Franziska Dessart: Das Erste, was mir da einfällt, ist auf jeden Fall: So ein Frontend–Framework ist ja jetzt meistens nicht so klein. Das heißt, ich muss es schon mal laden, und wenn ich dann zwei davon laden möchte, dann muss ich schon sehr viel laden. Und bei vielen Webseiten ist das so, dass man mit der Webseite noch nicht so viel anfangen kann, bevor das Framework geladen ist, und das heißt, der User muss erst mal ganz lange warten, bevor er etwas sieht, vielleicht sogar, oder zumindest, bis er dann irgendetwas tun kann mit der Seite. Also, die zwei Punkte “time to first meaningful paint” und “time to first interaction” – die Performance kann sich dadurch einfach drastisch verschlechtern.

Lucas Dohmen: Da gibt es auch eine eindrucksvolle Demo zu, die wir da verlinken können, in der jemand gezeigt hat, dass man ja in derselben App irgendwie React und Vue und Angular einsetzen könnte. Da wartet man wirklich sehr lange, bis die Seite fertig geladen ist, weil erst einmal all diese Einzelteile zusammengesteckt werden müssen und geladen werden müssen. Und je nachdem, wie leistungsfähig der Rechner von unserem Kunden oder von unserem Endanwender ist, kann das wirklich lange dauern, also auch einfach von der Performance her. Man darf nicht vergessen, dass man im Frontend ja über eine single–threaded environment spricht. Das heißt, alle diese Frameworks teilen sich dann einen Thread und daran führt auch kein Weg vorbei. Alle konkurrieren darum, auf diesem Thread jetzt an den Zug zu kommen und irgendetwas zu tun. Und das ist etwas anderes, als wenn wir im Backend jetzt einfach einen zweiten Server daneben setzen, auf dem jetzt statt Java 7 Java 8 läuft. Das ist einfach etwas ganz anderes, das kann man nicht so parallel vergleichen.

Stefan Tilkov: Okay. Wenn es also ein Spektrum gibt, dann liegt es ja nah, dass es zwischen diesen beiden Extremen, über die wir jetzt gesprochen haben, noch irgendetwas in der Mitte gibt. Kannst du da erklären, was das sein könnte?

Lucas Dohmen: Wir hätten als weitere Möglichkeit, was der Gustaf Nilsson Kotte vorgestellt hat, was die auch bei Ikea benutzen – dazu werden wir auch den Artikel verlinken in den Shownotes. Der ist grundsätzlich relativ nah an dem SCS–Ansatz, über den wir gesprochen haben. Der Hauptunterschied zwischen dem Ansatz von ihm und dem SCS–Ansatz ist, dass da ein ganz großer Fokus auf Transklusion liegt und der grundsätzlich auch erlaubt, dass das Rendern einer Seite erfordert, dass ganz viele verschiedene Systeme quasi zusammengesetzt werden müssen: Es gibt vielleicht ein Team, das für die Navigationsleiste zuständig ist und für den Footer. Und wenn jetzt die Seite gerendert werden muss, dann wartet das darauf, dass sowohl der Footer als auch der Header geladen wird. Und das wäre jetzt etwas, was beim SCS eigentlich nicht in Frage kommt, weil die ja unabhängig voneinander funktionieren können sollen. Das heißt, wenn ein anderes System ausfällt, dann lädt unsere Seite trotzdem. Das heißt, die Informationen, die wir einbetten von einem anderen System, sind Zusatzinformationen oder nebensächliche Informationen, ohne die unsere Seite trotzdem funktionieren könnte. Und das ist ein Constraint, den Gustaf aufhebt.

Stefan Tilkov: Okay.

Lucas Dohmen: Von meiner Interpretation her wäre das der Hauptunterschied zwischen diesen beiden Ansätzen. Denn grundsätzlich sind da sehr viele Ähnlichkeiten festzustellen zwischen SCS und seinem Ansatz und er geht auch sehr viel auf die Constraints ein, weswegen er sich für diesen Ansatz entschieden hat.

Genau. Und dann gäbe es als weiteren Ansatz den, der auf micro–frontends.org vorgestellt wird. Das ist ein Ansatz, der ein bisschen eher noch an diesem Ansatz mit den verschiedenen SPAs, die miteinander reden, ist. Da ist grundsätzlich für jede Seite ein bestimmtes SPA zuständig. Aber wir können Teile von anderen SPAs in unsere SPA hinein laden. Das heißt, in dem Gustaf–Ansatz wäre es jetzt nicht wünschenswert, dass wir jetzt irgendwie im Frontend React und Angular gleichzeitig laufen haben. Aber bei denen ist das durchaus denkbar, dass man das tut, dass das eine Team sich dafür entschieden hat, React ist das Beste für unsere Anwendung, deswegen nehmen wir für den Teil React und für den Teil nehmen wir Angular. Das war jetzt was, wo in dem Gustaf–Ansatz in der Transklusion eher HTML transkludiert wird. Und in dem Micro–Frontend–Ansatz – also das ist halt verwirrend, das der so heißt – in diesem micro–frontend.org–Ansatz würden wir durchaus auch sagen, wir laden eine Komponente, die dann mit einer JSON–API spricht und solange die ihre Inhalte nicht geladen hat, ist sie halt einfach eine weiße Komponente oder so. Also etwas, was bei dem Gustaf–Ansatz nicht da ist, vor allem, weil er auch sehr viel Wert auf server–seitiges Rendern für SEO legt, was natürlich aus der Perspektive von einem E–Commerce–Anbieter auch total viel Sinn ergibt. Da ist das sehr, sehr wichtig, dass unsere Seite server–seitig gerendert wird für SEO.

Stefan Tilkov: Wahrscheinlich können wir das kurz noch erwähnen: Ich glaube, der Gustaf–Ansatz heißt bei Gustaf microservice websites. Den Begriff hat er, glaube ich, irgendwo genommen, das können wir verwenden. Und ich habe neulich mit ihm einen anderen Podcast aufgenommen zu genau diesem Thema für die CaSE–Podcasts, den wir natürlich auch in den Shownotes verlinken. Also wer sich dafür tiefer interessiert, kann sich den (auf Englisch) natürlich auch noch anhören.

Lucas Dohmen: Genau.

Stefan Tilkov: Okay. Das heißt, jetzt habe ich das Kontinuum verstanden: Wir haben sozusagen im Prinzip auf dieser Achse immer mehr client–seitige Tätigkeit. Irgendwo in der Mitte schaltet es um von vorwiegend server–seitig gerendert auf vorwiegend client–seitig gerendert. Und das ist trotzdem alles irgendwie potentiell unter diesem Label Microfrontends zusammenzupacken. Gibt es denn irgendjemanden, der jetzt mal definitiv sagt, welches davon tatsächlich Microfrontends ist, Franzi?

Franziska Dessart: Nein. Also der Begriff ist, denke ich, recht populär, aber niemand hat da quasi den Hut auf. Was es auch noch gibt, vielleicht der Vollständigkeit halber zu erwähnen, ist, relativ weit auf der client–seitig gerenderten Seite, das Konzept mit den App–Shells. Also man hat quasi ein System, das so einen Rahmen vorgibt. Wenn der einmal geladen ist, dann sollte der auch gut cachebar sein und sollte dann auch schnell verfügbar sein. Der lädt sich dann den eigentlichen Inhalt der jeweiligen Bereiche aus verschiedenen anderen Systemen dazu. Das kennt man ja teilweise auch vom Desktop so, irgendwie, nä?

Stefan Tilkov: Wie so ein client–seitiges Portlet–Dingsbums oder so. Okay. Was machen wir denn jetzt daraus? Also, bevor wir unsere Hörer jetzt völlig verwirrt zurücklassen, können wir noch einmal ein bisschen über Vor– und Nachteile der verschiedenen Ansätze sprechen, denn die werden die ja offensichtlich haben?

Lucas Dohmen: Grundsätzlich hat das eigentlich immer den Nachteil, wenn man sehr intensiv auf client–seitige Frameworks zurückgreift, dass wir dem Client mehr Daten übertragen müssen. Gerade, wenn wir jetzt diesen Ansatz fahren, bei dem jede Komponente in jedem beliebigen Framework geschrieben sein kann, dann würden wir vielleicht fünf riesige Frameworks herunterladen. Das ist vermutlich etwas, was in der Praxis dann keiner tun würde. Weil das wäre dann vielleicht doch ein bisschen zu viel. Aber das wäre jetzt quasi das Extrem von diesem Ansatz, bei dem wir wirklich ganz, ganz viele Frameworks laden. Das hat halt vor allem den Nachteil, selbst wenn wir jetzt ignorieren, dass diese ganzen Daten heruntergeladen werden müssen von der Ausführungsgeschwindigkeit, weil einfach sehr, sehr viel Code auf diesem single–threaded environment im Browser ausgeführt werden muss. Diese Kosten bezahlen wir. Das heißt, wir sollten, wenn wir so einen Ansatz fahren möchten, sollten wir vielleicht einfach einmal einen Prototypen bauen und das ausprobieren – auch mit einem leistungsschwachen Gerät, auch einem leistungsschwachen Telefon beispielsweise, einfach mal ausprobieren, ob das da drin noch eine akzeptable Performance hat. Das wäre für mich der Hauptnachteil an diesem Ansatz, dass wir Performance und Größenprobleme bekommen.

Der Vorteil, den viele Leute an dem Ansatz sehen, ist, dass sie sich davon versprechen, besser interaktive Anwendungen zu bauen, die vielleicht auch teilweise offlinefähig sind. Offline–Fähigkeit ist etwas, was wir mit einem server–seitig gerenderten Ansatz immer schwerer hinbekommen. Das heißt, dann müssen wir mehr Arbeit hineinstecken, die Anwendung offlinefähig zu machen mit so etwas wie Service Workern und so weiter. Bei einem client–seitigen Ansatz können wir viele solche Sachen vielleicht schon auf dem Client machen und auch dann, wenn die Internetverbindung gerade vielleicht auch schlecht ist. Aber wir bezahlen das, indem wir mehr Ausführzeit und mehr Ladezeit bezahlen.

Franziska Dessart: Ja, ein anderer Punkt ist auch noch, dass ich nicht immer unbedingt JavaScript zur Verfügung habe. Also, weil es zum Beispiel gerade nicht geladen werden kann. Und wenn ich dem entgegen treten möchte und sage, ich sorge da jetzt vor, dass mein User dann nicht vor einer weißen Seite sitzt, dann muss ich so etwas machen wie Universal Web–Apps, die sowohl client– als auch server–seitig gerendert werden können. Und dann habe ich natürlich viel mehr Aufwand, mehr Komplexität und unter Umständen lädt der User das dann halt auch doppelt, wenn er in dem einen Moment kein JavaScript herunterladen kann und im nächsten dann doch. Ja, das ist auch noch ein anderer Punkt.

Stefan Tilkov: Also, darin steckt ja eine signifikante Entwicklungsleistung, dieses Problem zu lösen, im Client diese unterschiedlichen Frameworks zusammenzupacken. Das macht man ja nicht mit einem Fingerschnippen, sondern darüber muss man sich ja schon Gedanken machen, wie man das hinbekommt. Warum würde man das denn wollen wollen, das habe ich noch nicht ganz kapiert. Könnt ihr mir das erklären?

Lucas Dohmen: Es gibt jetzt eine nette und eine böse Antwort darauf. Die böse Antwort, die auch meine Meinung ist zu dem Thema, ist, dass viele Leute halt einfach viel investiert haben in diese single–page frameworks und darin viel Code geschrieben haben und das toll finden und sich darin auch produktiv fühlen. Und die haben jetzt bemerkt, dass irgendwann diese Anwendungen zu groß werden, haben vielleicht auch diese schmerzhafte Angular 1 zu Angular 2 Transition mitgemacht oder andere Unternehmen daran Pleite gehen sehen. Und die wollen jetzt quasi nicht alles über Bord werfen, sondern die wollen halt die Technologie beibehalten und die Probleme irgendwie lösen. Aber das, was dabei herauskommt, ist fraglich in seiner Qualität. Also, gerade wenn ich mir vorstelle, irgendwie zwei Angular–Versionen gleichzeitig im Browser zu laden, das kann ich mir nicht vorstellen, dass das jemand performant und gut hinbekommt. Die nette Version habe ich, glaube ich, vergessen. Aber das ist meine Einschätzung.

Stefan Tilkov: So böse war die ja gar nicht, die Version gerade.

Lucas Dohmen: Okay. Das ist meine Einschätzung der Situation, warum viele Leute das überhaupt versuchen. Weil ich glaube, das ist einfach ein Ansatz, der zutiefst zweifelhaft ist.

Stefan Tilkov: Okay. Gut, ich glaube, wir sind schon am Ende unseres Zeitbudgets und auch mit der Tiefe, mit der wir das normalerweise machen, durch das Thema eigentlich durch. Wir haben ganz bestimmt diesmal ganz besonders viele Links in den Shownotes zu allen möglichen Seiten, allen möglichen Dingen. Es gibt eine sehr schöne Übersichtsseite von der Elisabeth Engel, die ganz viele Sachen gesammelt hat, die sich zum Teil auch dramatisch widersprechen; man sieht also, dass das doch sehr stark im Fluss ist. Ich danke euch für eure Zeit, es hat viel Spaß gemacht, danke fürs Mitmachen.

Lucas Dohmen: Sehr gerne.

Stefan Tilkov: Und danke an die Zuhörer fürs Zuhören. Bis zum nächsten Mal. Tschüss.

Lucas Dohmen: Ciao.

Franziska Dessart: Tschüss.

In Memoriam ∞ CEO & Principal Consultant

Stefan Tilkov war Geschäftsführer und Principal Consultant bei INNOQ Deutschland, wo er sich vorwiegend mit der strategischen Beratung von Kunden im Umfeld von Softwarearchitekturen beschäftigte. Er war Autor des Buchs “REST und HTTP”, Mitherausgeber von “SOA-Expertenwissen” (beide dpunkt.verlag), Autor zahlreicher Fachartikel und häufiger Sprecher auf internationalen Konferenzen.

Wir trauern um Stefan.

Senior Consultant

Franziska Dessart ist Senior Consultant bei INNOQ. Sie entwickelt seit mehr als 15 Jahren für das Web und begeistert sich für Architekturen wie Self-Contained Systems und Microfrontends. Am liebsten arbeitet sie im Remote Mob.

Alumnus

Lucas war bis August 2023 Senior Consultant bei INNOQ. Er beschäftigt sich mit der Architektur, Konzeption und Umsetzung von Web Anwendungen in Front- und Backend. Er programmiert in Ruby und JavaScript und hilft bei der Entscheidung und Einführung verschiedener NoSQL Lösungen. Lucas ist Autor des Buchs “The Rails 7 Way”. Seine Stimme ist regelmäßig im INNOQ Podcast zu hören. Außerhalb seiner Arbeit beschäftigt er sich mit Open Source und Community Arbeit (wie die Organisation und das Coaching beim lokalen CoderDojo).