Warum Flutter die Antwort auf die fragmentierte mobile Welt sein kann.

Die Welt ist mobil. Immer mehr Menschen nutzen Smartphones und Tablets, um im Internet zu surfen, zu kommunizieren, zu spielen, zu lernen und zu arbeiten. Laut Statista gab es im Jahr 2022 weltweit rund 6,5 Milliarden Smartphone-Nutzer:innen. Diese Zahl wird voraussichtlich bis 2028 auf 7,7 Milliarden ansteigen. Doch die mobile Landschaft ist fragmentiert: Es gibt verschiedene Betriebssysteme, wie Android und iOS. Ganz besonders bei Android ist auch noch die Verteilung auf die unterschiedlichen Betriebssystemversionen und Hersteller zu berücksichtigen. Wie kann man also eine App erstellen, die auf allen Plattformen funktioniert, ohne viel Zeit und Geld zu investieren?

Eine Antwort lautet: Flutter. Flutter ist ein quelloffenes Framework von Google, das es ermöglicht, nativ wirkende Apps für verschiedene Plattformen mit einer einzigen Codebasis zu entwickeln. Das bedeutet, dass man eine App nur einmal programmieren muss und nicht für jede Plattform einzeln. Sie läuft dann prinzipiell auf Android, Wear OS, iOS, macOS, iPadOS, Windows, Linux und im Web. Ziele von Flutter sind unter anderem, die Wiederverwendbarkeit von Code auf den genannten Plattformen zu ermöglichen, dabei eine Performance zu gewährleisten, die mit nativen Apps mithalten kann und die einzigartigen Möglichkeiten der jeweiligen Plattform zu unterstützen. Zudem sollen schnelle Entwicklungszyklen ermöglicht werden. Dass Flutter eine immer größere Rolle in der Cross-Plattform-Entwicklung einnimmt, lässt sich an der Statistik zu den von Software-Entwickler:innen weltweit eingesetzten Cross-Plattform-Technologien von 2019 bis 2022 erkennen.

Auf jeden Fall war ich sehr überrascht, wie nativ es sich anfühlt. Da hatten wir alle, glaube ich, vorher so ein bisschen Bedenken [...] und können wir das genauso übersetzen in Flutter? Aber das hat sich ja relativ schnell einfach nicht bestätigt, dass das so ist, sondern ließ sich ja extrem gut genauso umsetzen, wie wir es nativ auch hatten. Das hat mich so ein Stück weit schon überrascht, dass es damit so easy möglich war.

Ulrike – UX Designer bei slashwhy

Wie erreicht Flutter die selbstgesteckten Ziele?

Flutter rendert alle UI-Elemente selbst. Anders als React Native oder .NET MAUI setzt Flutter nicht darauf, Bindings für die nativen Komponenten wie beispielsweise Buttons, Navigation Bars oder Textfelder zur Verfügung zu stellen und damit eine weitere Schicht über die nativen Elemente zu legen. Dies ist der fundamentale Unterschied zu anderen populären mobilen Technologien, welche es vor Flutter gab. Das selbstständige Rendering ermöglicht das Ausführen von Flutter Apps auf potenziell jeder Plattform. Eine wichtige Voraussetzung ist jedoch, dass für die jeweilige Plattform ein Embedder existiert. Embedder sorgen für die Kommunikation der plattformunabhängigen Komponenten mit den Plattformabhängigen. Ein Beispiel: Es wäre schlecht, wenn das Drücken von einzelnen Tasten auf der Tastatur nicht zu diesem Blogpost führen würden, weil ein Embedder die Signale dafür nicht weiterleitet. Durch die Unabhängigkeit von plattform-spezifischen UI Rendering Engines, sind Entwickler:innen befähigt, annähernd jede Idee, die sich ein UX-Designer:innen ausmalen kann, in kürzerer Zeit umzusetzen.

Um schnelle Entwicklungszyklen zu ermöglichen, bietet Flutter vorgefertigte UI-Elemente an. Diese werden auf Basis der Human-Interface-Guidelines (Apple) und den Material-Guidelines (Google) vom Flutter-Team zur Verfügung gestellt. Darüberhinaus besteht die Möglichkeit, Anwendungen für z.B. Windows oder Linux Desktops so aussehen zu lassen, wie es Nutzer:innen in der jeweiligen Umgebung erwarten. Dafür vorgesehen Bibliotheken erleichtern die Umsetzung.

Außerdem ermöglicht Flutter ein schnelles Ausprobieren von UI-Änderungen durch die Features Hot Reload und Hot Restart: Die App muss nicht für jede Änderung erneut gebaut werden und es muss auch keine Navigation zur geänderten Komponente stattfinden. Dadurch können die gewonnenen Erkenntnisse, die während des Austauschs zwischen Entwickler:innen und Designer:innen entstehen, direkt integriert und unterschiedliche Variationen sofort und ohne lange Wartezeiten gemeinsam ausprobiert werden.

In das Ziel „native Performance“ hat das Flutter-Team in den letzten zwei Jahren massiv investiert: In den Anfängen von Flutter fielen mit Flutter entwickelte Apps durch leichte Ruckler bei Seitenübergängen beim ersten Laden auf. Hier wurden Shader während des Ladens der Flutter Engine - also während des Appstarts und während der Navigation auf die nächste Seite – geladen. Das heißt, dass die kleinen Programme, die für die Farbgebung der einzelnen Pixel auf dem Bildschirm sorgen, nicht während die App bei App-Entwickler:innen auf dem Computer kompiliert, sondern auf den Endgeräten der Nutzer:innen geladen wurden. In den neueren Versionen von Flutter ist dieser Designfehler in der Software beseitigt, sodass durchgängig Bildwiederholungsraten von über 60fps auf Geräten mit schwacher Hardware und hardwarebeschleunigt 120fps erreicht werden. Gerade liegt der Fokus des Flutter Teams darauf, im Web direkt zu WebAssembly zu kompilieren anstatt zu JavaScript zu cross-kompilieren, was die Performance für mit Flutter programmierte Webanwendungen verbessern soll.

Das Ziel die einzigartigen Möglichkeiten der jeweiligen Plattformen voll auszuschöpfen, wird durch sogenannte Plattform Channels oder Bindings gelöst: Mit diesen kann man direkt auf die Schnittstellen der jeweiligen Plattform zugreifen. Beispielsweise können so lokale Benachrichtigungen ausgelöst oder Companion Devices gesteuert werden. Für die meisten dieser Anwendungsfälle gibt es bereits Abstraktionen von der mannigfaltigen Community, sodass man mit dem Konstrukt „Plattform Channel“ höchstwahrscheinlich nicht in Berührung kommt. Sollte die Anforderung jedoch über die bereits existierenden Plugins hinaus gehen, ist die Freiheit gegeben, relativ einfach auf die nativen Komponenten zuzugreifen.

Flutter kritisch hinterfragt

Obwohl wir sehr von den Möglichkeiten, die Flutter bietet, überzeugt sind, wollen wir Nachteile, die Flutter mit sich bringt, nicht verschweigen:

Obwohl es möglich ist, native Komponenten in Flutter einzubinden, ist dies nicht der empfohlene Weg für die „normalen“ Flutter-Entwickler:innen. Hier sei darauf verwiesen, dass man sowohl native Komponenten in Flutter als auch Flutter in native Apps laden kann. Der Vorteil, dass Flutter alle Komponenten selbst rendert und nicht über Bindings die nativen Komponenten anspricht, ist ein zweischneidiges Schwert: Komponenten die von Apple, Google oder Microsoft auf der WWDC, Google IO oder Microsoft Ignite am Vortag vorgestellt wurden, werden nicht am nächsten Tag in Flutter zur Verfügung stehen. Es muss abgewogen werden: Wenn das zu entwickelnde Produkt die neuesten Komponenten benötigt, muss man diese selbst schreiben oder darauf warten, dass das Team um Flutter diese zur Verfügung stellt. Sollte die Entscheidung zu oft auf selbstgeschriebene Komponenten fallen, sollte die Applikation besser nativ entwickelt werden. Darüber hinaus beschränkt sich das Selbstrendern der UI nicht nur auf die direkt in Apps verwendete Viewkomponenten, wie z.B. Buttons oder Textfelder, sondern umfasst auch vermeintliche System-UI, wie z.B. zur Textauswahl. Sollte es hierbei also Anpassungen geben, muss das Flutter Entwicklungsteam reagieren – idealerweise so, dass eine zum jeweils echten Betriebssystemverhalten passende Flutter-Implementierung verwendet wird.

Darüber hinaus kann es auch abseits vom UI Rendering so sein, dass keine nativen Implementierungen verwendet werden. So verwendet das http-Package von Flutter derzeit noch eine Dart-Bibliothek zur per SSL/TLS gesicherten Kommunikation und nicht etwa die dazu eigentlich vorgesehenen nativen Schnittstellen, wenn man die Standardkonfiguration übernimmt. In diesem konkreten Fall bedeutet das, dass sicherheitsrelevante Updates mit der App ausgeliefert werden müssen, obwohl sie üblicherweise per Betriebssystem-Update App-übergreifend ausgeliefert würden.

Ein weiterer Punkt, den man sich bewusst machen sollte, ist, dass Flutter-Applikationen mit der Programmiersprache Dart entwickelt werden und das Erlernen einer neuen Programmiersprache bzw. eines neuen Frameworks Zeit kosten kann. Dart ist bisher neben z.B. Java/Kotlin, JavaScript oder C# noch nicht so verbreitet, wie man einer aktuellen Umfrage von StackOverflow entnehmen kann. Mit einer Programmiersprache bzw. einem Framework kommen meistens auch ein paar neue Eigenheiten und Best Practices dazu. Ein Beispiel hierfür ist, dass mit Flutter penibel darauf zu achten ist, dass sich wiederholende Komponenten, die ihre Position in der UI vertauschen können, ein eindeutiges Identifizierungsmerkmal bekommen. Sonst führt das unweigerlich zu unerwarteten Problemen.

Wie bei jeder Technologie wird das Leben von Entwickler:innen erst spannend, wenn man über die „Hello World“-Anwendung hinaus skalieren will. Denn dann muss man sich über die Testbarkeit, Wartbarkeit und Erweiterbarkeit, wie man Zustände vorhält und wie diese persistiert werden – sprich die Architektur – Gedanken machen. In all das müssen sich neue Entwickler:innen erst einarbeiten und Erfahrung sammeln. Wir bei slashwhy haben ein Template entwickelt, das eine Struktur mitbringt, die einen besonders schnellen Einstieg in ein neues Projekt bietet. In unserem Template sind Themen wie CI-/CD-Pipelines, typensichere Parameterübergabe bei der Navigation, Übersetzungen, Clean Architecture und Dependency Injection – um nur ein Paar zu nennen – schon berücksichtigt oder enthalten. Dies ermöglicht uns bei Projektbeginn ein früheres Durchstarten.

Je nach Anwendungsgebiet und Verteilungsweg der zu entwicklenden App, sollten Entwickler:innen im Hinterkopf behalten, dass mit Flutter entwickelte Apps in der Regel wenige MB größer als nativ entwickelte Pendants ausfallen. So tragen Flutter-Engine und andere Komponenten des Frameworks zur Appgröße bei.

Was sind die Auswirkungen auf den Entwicklungsprozess?

Einer der Claims bei slashwhy ist „Make people happy“. Damit meinen wir nicht nur unsere Kunden:innen und die Nutzer:innen unserer Software, sondern auch diejenigen, die bei uns Softwareprodukte gestalten und umsetzen. Deshalb wollen wir in diesem Abschnitt auch die Auswirkungen von Flutter auf unsere eigene Arbeit beleuchten.

Mit Flutter können wir dank der Features wie Hot Reload und Hot Restart schnell und einfach Apps entwickeln. Mit diesen Features wird die Developer Experience stark verbessert, weil sie uns erlauben, Änderungen am Code sofort auf dem Gerät zu sehen, ohne die App neu zu starten oder den Zustand zu verlieren. Das führt automatisch zu einer engeren Zusammenarbeit mit unseren Designer:innen, da bei UI/UX-Reviews der umgesetzten Features nicht immer erst auf einen Build der Software gewartet werden muss, sondern diese in einem Call oder direkt vor Ort besprochen und finalisiert werden können.

[...] ich glaube, der größte Vorteil ist [...] Hot Reload. [...] gemeinsam mal eben Dinge zu entwickeln, war ein Riesenvorteil. Dadurch, dass man schnell visuell die Ergebnisse prüfen konnte, war die Zusammenarbeit enger als in der nativen Entwicklung. Also [in der nativen Entwicklung] ist es so, hier ist das Design, Entwickler:innen nehmen sich das Design, setzen es um, ohne dass ich es mitbegleite, und zeigen mir das Resultat. Ich gebe Feedback und dann nimmt er sich das wieder mit - bei Flutter war die Zusammenarbeit viel enger.

Ulrike – UX Designer bei slashwhy

Als Entwickler:innen einer qualitativ hochwertigen Software schläft man beruhigt, wenn man weiß, dass eine neu hinzugefügte Funktionalität keine negative Auswirkung auf bereits bestehenden Code hat und die neue Funktionalität auch in Grenzfällen einwandfrei funktioniert. Sichergestellt wird dies unter anderem durch automatisierte Tests, welche mit Flutter auf mehreren Ebenen möglich sind:

  • Wir können Unit-Tests schreiben, um einzelne Funktionen oder Klassen zu prüfen.

  • Widget Tests lassen uns das Verhalten einzelner Widgets prüfen. Das heißt, dass wir das Verhalten einzelner UI-Komponenten isoliert testen können.

  • Und zusätzlich lassen sich Integrationstests umsetzen, die das Zusammenspiel mehrerer Widgets oder komplette Flows durch die App prüfen.

Gerade Widget-Tests sind wegen der Unit-Test ähnlichen Ausführungszeit ein riesiger Vorteil. Es kann innerhalb weniger Sekunden sichergestellt werden, dass Komponenten auch nach Änderungen noch wie vorgesehen funktionieren. Etwas Vergleichbares gibt es bei .NET MAUI bislang nicht.

Weiterhin sind die sehr gute Dokumentation und die vielen Ressourcen zum Lernen von Flutter zu erwähnen. Die Möglichkeit Flutter im Browser auszuführen wird in der Dokumentation auf der Flutter-Website genutzt, um die Widgets direkt verproben zu können.

Die Dokumentation ist extrem gut. Auch durch die Live-Code-Snippet, welche sie da haben zum Ausprobieren und Sachen ändern und verstehen, wie sie funktionieren. Ist bis jetzt die beste Ground Framework-Dokumentation, mit der ich gearbeitet habe.

Steffen – Mobile Software Engineer bei slashwhy

Des Weiteren haben wir festgestellt, dass Flutter mittlerweile von einer großen und engagierten Community lebt, die ständig neue Plugins, Packages, Tutorials, Artikel, Videos (z.B. Widget of the Week) und vieles mehr erstellt und teilt. Wir können jederzeit Hilfe oder Inspiration von anderen Entwickler:innen bekommen oder selbst etwas zur Community beitragen.

Wann ist Flutter für dein Projekt geeignet?

Generell ist es uns bei slashwhy sehr wichtig, keine pauschalen Empfehlungen auszusprechen, sondern immer für den genauen Case der Kunden:innen die bestmögliche Auswahl zu treffen und dies durch Technologieworkshops und Research zu unterstützen.

In diesem Entscheidungsprozess bietet Flutter die folgenden Vorteile für Kunden, die eine mobile App für ihr Geschäft oder ihre Marke benötigen:

  • Kosteneffizienz: Mit Flutter kann man eine App für mehrere Plattformen mit einer einzigen Codebasis entwickeln. Das spart Zeit und Geld, die sonst für die Anpassung an verschiedene Betriebssysteme und Geräte aufgewendet werden müssten. Zudem ist Flutter quelloffen und die Verwendung kostenlos.

  • Flexibilität: Mit Flutter kann man jede Art von App erstellen, von einfachen bis hin zu komplexen Anwendungen. Flutter bietet eine große Auswahl an Widgets und Packages, die viele Funktionen abdecken, wie Navigation, Animation, Datenbank- und Netzwerkzugriff, Authentifizierung und vieles mehr. Außerdem kann man auch auf native Funktionen zugreifen oder eigene Widgets erstellen.

  • Qualität: Mit Flutter kann man hochwertige Apps erstellen, die eine hohe Leistung und flüssige Animationen bieten. Flutter unterstützt auch Tests und Debugging auf verschiedenen Ebenen, um Fehler zu vermeiden oder zu beheben.

  • Portabilität: Es ist möglich, Projekte auch auf weitere Plattformen wie Desktop oder Web zu bringen, ohne die App von Grund auf neu entwickeln zu müssen.

Selbst bei Apps, deren Umsetzung zunächst für nur eine Plattform gedacht ist, kann Flutter eine geeignete Wahl sein. Einerseits zeigt unsere Erfahrung in der Entwicklung von Apps, dass im Laufe der Entwicklung oder nach Release auch die jeweils andere Plattform unterstützt werden soll. Andererseits sind uns bislang keine schwerwiegenden Gründe aufgefallen, die ein erfahrenes Flutter-Team grundsätzlich zur Entwicklung einer nativen App bewegen sollten.

Wann ist Flutter für dein Projekt nicht geeignet?

Wie schon ausgeführt – Flutter sollte nicht gewählt werden, wenn die zu entwickelnde Applikation immer die neuesten UI-Komponenten, die die jeweiligen SDKs bieten oder sehr stark auf Downloadgröße geachtet werden muss. Außerdem sollte geprüft werden, dass die Zielplattform(en) im benötigten Umfang unterstützt werden.

Zusammenfassung und Ausblick

Du hast es beim Lesen vermutlich schon gemerkt: wir haben spannende Projekte mit Flutter umgesetzt und freuen uns auf weitere. Doch (auch) am Anfang eines jeden Projekts steht bei uns nicht etwa die Technologie, sondern Nutzer:innen und deren Bedürfnisse im Vordergrund. Erst wenn grundlegenden funktionale und nicht-funktionalen Anforderungen klar sind, kann ein geeigneter Technologiestack zur Implementierung ausgewählt werden. Durch Flutters große Bandbreite an Plattformen und Möglichkeiten können wir es je doch in vielen Fällen empfehlen.

Nicht nur wir, sondern auch viele andere Entwickler auf diesem Planeten scheinen vom Flutter-Ökosystem überzeugt zu sein. Statisiken bescheinigen der Technologie über die letzten Jahre ein sehr starkes Wachstum und auch große Unternehmen wie beispielsweise BMW, Toyota, eBay oder iRobot setzen darauf.

Die Hauptsache ist jedoch, dass die Endnutzer:innen das Produkt gerne nutzen möchten: Wir sind auf Ideengeber:innen wie unsere Kunden:innen angewiesen, damit wir nicht nur technologisch großartige Software entwickeln können. Wenn du eine Idee hast, komme auf uns zu und wir schauen gemeinsam – z.B. in einem Workshop – welche Technologien für die Erfüllung der Anforderungen deiner Nutzer:innen geeignet sind. Bis dahin!

Über die Autoren

  • tobias-busch-slashwhy

    Über Tobias Busch

    Wie kann man als Software Engineer bei slashwhy großartige, nutzerzentrierte Produkte entwickeln? Diese Frage treibt Tobi an. Er ist auf mobile Anwendungen spezialisiert und beschäftigt sich gerade intensiv mit Künstlicher Intelligenz. Er achtet nicht nur auf technische Details, sondern auch auf die organisatorischen Aspekte. Durch die Erfahrungen als Scrum Master optimiert er Prozesse in crossfunktionalen Teams und verfolgt einen ganzheitlichen Ansatz bei der App-Entwicklung.

  • stephan-vosskuhl-slashwhy

    Über Stephan Voskuhl

    Gib Stephan einen Berg an Problem und er fängt an zu schaufeln: Komplexe Problemstellungen mit neuen Ansätzen zu lösen sind seine Spezialität. Ob diese im Bereich Infrastruktur, Architektur, Mobile, Computer Vision, Backend oder Frontend zu finden sind, ist zweitrangig. Die Hauptsache für Stephan ist, dass mit einem Produkt Lösungen für echte Nutzer geschaffen werden.