Warum gewinnt Flutter?

Letztes Jahr habe ich sowieso Flutter-Apps für iOS und Android geschrieben. Davor hatte und habe ich 5 Jahre Erfahrung mit Xamarin. Es waren wundervolle 5 Jahre. Dank Xamarin und meiner Liebe zu diesem Framework bin ich im Prinzip in das Entwicklerlager gezogen. Mit diesem Tool konnte ich viel Geld und Wissen verdienen und wunderbare Kollegen finden. Warum schreibe ich jetzt auf Flutter? Kurze Antwort, denn Flutter deckt alle Anforderungen der plattformübergreifenden Entwicklung ab.


Ein bisschen Geschichte


Korrigieren Sie mich, wenn ich falsch liege, aber 2009 war in vielerlei Hinsicht der Schlüssel für die mobile Entwicklung im Allgemeinen und die plattformübergreifende Entwicklung im Besonderen. Im Jahr 2009 wurde das iPhone 3gs veröffentlicht, mit dem Sie Anwendungen von Drittanbietern im AppStore ausführen können. Zum ersten Mal erschien diese Gelegenheit ein Jahr zuvor im iPhone 3g, aber 3gs ist zu einem wirklich massiven, „beliebten“ iPhone geworden. Ein Jahr zuvor, im September 2008, wurde Android erneut der Öffentlichkeit vorgestellt, und 2009 begannen viele Telefonhersteller, Android für ihre neuen Telefonmodelle auszuprobieren. Im Frühjahr 2009 führte Nitobi PhoneGap ein, ein neues Framework zum Erstellen plattformübergreifender Anwendungen auf Basis von HTML5, CSS und JS. Im selben Jahr, im SeptemberXimian hat MonoTouch veröffentlicht, mit dem Sie iOS-Anwendungen mit Mono und C # schreiben können. Im selben Jahr 2009, im Dezember, veröffentlichte Rovio Entertainment ein Spiel für iOS und für einen Moment für Maemo, das in vielerlei Hinsicht den Beginn der Handyspielbranche markierte - Angry Birds. Das letzte Beispiel hier ist nicht zufällig.

Das erste plattformübergreifende Framework "für die Menschen" kann als PhoneGap betrachtet werden (Qt-Entwickler werfen keine Steine). Es war eine wunderbare und sehr offensichtliche Idee, das Web in die Welt der mobilen Entwicklung zu bringen. Bis 2009 gingen die Funktionen des Webs bereits über den Browser hinaus ( hallo node.js), während das Schreiben von Webanwendungen in JS ziemlich einfach war. Der zweite, nicht weniger wichtige Punkt ist das Rendern der Benutzeroberfläche. Die Art und Weise, wie das Rendern erfolgt, liegt bei der Browser-Engine, und alle diese Engines folgen mehr oder weniger den W3C-Standards für HTML, CSS und DOM. Jeder Webentwickler, der eine Website erstellt hat, erwartet, dass seine Website fast so aussiehtidentisch in jedem Browser, auf jeder Plattform. Dies ist meiner Meinung nach der wichtigste Aspekt des Web als offene Plattform. Warum sollte ich für jede Plattform eine neue Sprache / ein neues Framework zum Zeichnen der Benutzeroberfläche lernen, wenn es seit langem einen Standard für die Modellierung der Benutzeroberfläche für verschiedene Browser gibt?

Danach drehte sich Cordova von PhoneGap und von Ionic ab. Es scheint, dass dies ein idealer Rahmen ist, aber es gab zwei Punkte: Leistung und Betriebssystemintegration. Eines der Hauptziele oder, wenn Sie möchten, Anwendungsbenchmarks, die für plattformübergreifende Lösungen geschrieben wurden, war ihre "Ursprünglichkeit". Jene. Im Idealfall sollten 100% der Benutzer berücksichtigen, dass Ihre plattformübergreifende Anwendung nativ ist. Und das bedeutet, dass es wie native aussehen sollte, wie native funktionieren und alle möglichen Integrationen mit dem Betriebssystem haben sollte. Am Anfang waren all diese Punkte für PhoneGap unerreichbar, die Kapazitäten von Smartphones vor 10 Jahren reichten für das Rendern der Benutzeroberfläche mit 60 fps nicht aus, die Integration in das Betriebssystem war minimal. Jetzt gibt es auf Ionic einige Anwendungen, die schwer von nativen zu unterscheiden sind, aber die Nachahmung einer nativen Anwendung ist immer noch eine Aufgabe.und nicht als solche gegeben. Lassen Sie uns ein wenig zusammenfassen. Das Schreiben von Webanwendungen bzw. Hybridanwendungen auf iOS und Android ist möglich und bequem. Dies ist praktisch, da der UI-Rendering-Mechanismus vollständig auf der WebView-Plattform liegt und es bereits eine geschulte Schicht von Programmierern gibt, die sich im Web gut auskennen.In Hybridanwendungen können Leistung und Betriebssystemintegration jedoch lahm sein.

Gleichzeitig mit PhoneGap wurde 2009 MonoTouch gestartet, das später in Xamarin.iOS umbenannt wurde. Im selben Jahr wurde auch Titan veröffentlicht, was wiederum das Schreiben von iOS-Anwendungen auf Javascript ermöglichte. Zunächst arbeitete Titanium genau nach dem gleichen Paradigma wie PhoneGap - basierend auf WebView. Aber dann haben sie den Xamarin-Ansatz gewählt. Was ist dieser Ansatz? Es kann als etwas in der Mitte gesehen werden. Der Ansatz von Xamarin / Titanium / React.Native besteht darin, dass das Framework nicht versucht, Ihr / vorhandenes UI-Rendering zu erstellen / zu migrieren, sondern einfach in das vorhandene native integriert wird.

Anstatt ein Formular in HTML zu zeichnen, ruft Xamarin hierfür ein natives UI-Element auf (UITextField, TextEdit usw.). Warum das Rad neu erfinden? Alle erforderlichen UI-Elemente sind in nativen SDKs und Laufzeiten vorhanden. Sie müssen lediglich lernen, wie Sie von Ihren VMs (Mono, Version 8 usw.) mit ihnen kommunizieren. Gleichzeitig können Sie, wie Sie bereits vermutet haben, Ihr bevorzugtes C #, JS, TS, F #, Kotlin usw. verwenden, und gleichzeitig ist Code, der nicht direkt mit der Benutzeroberfläche interagiert, zu 100% plattformübergreifend. Sie können noch weiter gehen. Dasselbe UITextField und TextEdit sind konzeptionell identische Entitäten, sie haben einige ähnliche Eigenschaften und Interaktionsschnittstellen. Daher können Sie einen abstrakten Eintrag erstellen (Hallo Xamarin.Forms) und nur selten damit arbeiten ( nicht sehr)) Ausnahme, die sich auf das Element der Plattform-Benutzeroberfläche bezieht. Ich erwähne nicht, dass, wenn Ihre VM nativ mit der Benutzeroberfläche arbeiten kann, Ihre VM höchstwahrscheinlich alle Plattform-APIs aufrufen kann. Dies scheint die perfekte Option zu sein. Native Benutzeroberfläche, native Leistung (hi Bridges in React.Native), 100% Betriebssystemintegration. Ist das wirklich perfekt? Höchstwahrscheinlich - nein, und das Problem ist, dass diese Lösungen in Wirklichkeit das Problem der plattformübergreifenden Entwicklung nicht lösen - eine einzige Benutzeroberfläche. Sie verkleiden sie. Ich möchte einmal schreiben, überall laufen. Dies ist bei weitem nicht das beste Motto für alle Arten von Programmen und Problemen, passt aber gut zur Benutzeroberfläche. Ich möchte die Benutzeroberfläche für alle gleich schreiben, unabhängig von der Plattform. Warum kann sich ein Webentwickler erlauben, mit HTML und CSS eine Site zu schreiben, die dann in Safari unter iOS und Chrome unter Android auf dieselbe Weise angezeigt wird, aber kein nativer Entwickler?

Tatsächlich haben Programmierer seit langem eine leistungsstarke Benutzeroberfläche mit einer gemeinsamen Codebasis für iOS und Android geschrieben. Diese Programmierer werden Spieleentwickler genannt. Angry Birds wurde für die Cocos2d-x-Engine, Cuphead für Unity und Fortnite für Unreal Engine geschrieben. Wenn Game Engines atemberaubende Szenen auf Ihrem Handy anzeigen können, können Schaltflächen und Listen mit flüssiger Animation dies auf jeden Fall. Warum benutzt sie niemand in diesem Sinne? Die Antwort ist einfach und banal, sie sind nicht dafür gedacht. Wenn Sie das Spiel öffnen, hängt es absolut von der Taschenlampe ab, wie sehr die Benutzeroberfläche wie eine native aussieht. Sie müssen fast nie mit Geolokalisierung, Drucktasten, einer Videokamera usw. interagieren. Während Sie spielen, leben Sie ein anderes Leben in Ihrer kleinen Welt, das durch Canvas in Ihrem UIViewController / Ihrer Aktivität gerendert wird. deshalbGame-Engines sind relativ schlecht in das Betriebssystem integriert , daher gibt es keine (oder ich habe nicht gesehen) Nachahmung der nativen UI-Top-Engine.

Zwischensummen


Für ein ideales plattformübergreifendes Framework benötigen wir:

  • Native UI-Zuordnung
  • Native UI-Leistung
  • 100% ige Fähigkeit, jede Betriebssystem-API aufzurufen, als wäre es eine native Anwendung

Sie denken jetzt, dass ich unter Flutter anfangen werde zu scheitern, aber ich höre bereits wütende Kommentare: „Wo ist Qt !? Er kann das alles! “ In der Tat entspricht Qt bis zu dem einen oder anderen Grad diesen Kriterien. Obwohl ich den ersten stark bezweifle. Das Hauptproblem von Qt ist jedoch nicht die Schwierigkeit, eine native Benutzeroberfläche zu schreiben. Das Hauptproblem ist C ++. Dann wische ich mir schon das Gesicht von der Spucke der Labour-Encoder auf den Pluspunkten. Pros ist ein Schweizer Messer gegen Anabolika, mit den Profis kann man alles machen. Aber ich als Frontend-Entwickler brauche das alles nicht. Ich brauche eine einfache und verständliche Sprache, die mit UI und I / O funktioniert. Zu unseren drei obigen Punkten wurde also Folgendes hinzugefügt:

  • Leicht zu lernen und sehr ausdrucksstarke Sprache
  • Rantime, die gut in das Frontend-Entwicklungsparadigma passt

Nun, da wir einige Metriken eines guten plattformübergreifenden Tools für die Entwicklung mobiler Anwendungen hervorgehoben haben, können wir uns jedes einzelne davon ansehen und sehen, wie es in Flutter implementiert ist.

Native UI-Zuordnung



Wie wir zuvor herausgefunden haben, gibt es zwei entgegengesetzte Ansätze für die Arbeit mit der Benutzeroberfläche in plattformübergreifenden Frameworks. Dies ist ein UI-Rendering mit WebView oder nativen UI-Elementaufrufen auf jeder Plattform. Jeder Ansatz hat Vor- und Nachteile. Sie decken jedoch nicht alle Entwickleranforderungen ab: Sie unterscheiden sich nicht von der nativen Benutzeroberfläche + der nativen Leistung. Flutter deckt all diese Bedürfnisse mit einem Kopf ab. Das Flutter-Team hat eine bestimmte Menge an Ressourcen für die Erstellung „nativer“ Elemente im Framework selbst aufgewendet. Alle Widgets in Flutter sind in drei große Kategorien unterteilt:


Wenn Sie zum Abschnitt cupertino gehen, werden Sie feststellen, dass diese Widgets nicht von nativen iOS-Elementen zu unterscheiden sind. Als Entwickler, der Flutter seit einiger Zeit verwendet, kann ich bestätigen, dass sie nicht zu unterscheiden sind. Wenn Sie beispielsweise CupertinoDatePicker verwenden, werden Sie beim Scrollen genau das gleiche, nette Feedback von der Taptic / Haptic-Engine auf Ihrem iPhone erhalten, als wäre es ein natives Element der nativen Anwendung. Ich werde mehr sagen, ich öffne regelmäßig die Anwendung der Website realtor.com auf meinem iPhone und hatte bis vor kurzem keine Ahnung, dass sie in Flutter (oder auf etwas nicht Native) geschrieben wurde.

Mit Flutter können Sie nicht nur "native" Widgets für 2 Plattformen verwenden, sondern auch eigene erstellen, und das ist ganz einfach! Das ganze Paradigma ist, dass alles Widget funktioniert. Sie können in kurzer Zeit erstaunlich komplexe UI-Elemente und Animationen erstellen. Der Charme und die Weisheit des Ansatzes zur Arbeit mit der Benutzeroberfläche in Flutter wurden kürzlich in diesem Artikel über Habr beschrieben. Ich empfehle das Lesen. weil All dies funktioniert auf einer einzigen Grafik-Engine, die all dies für jede Plattform direkt wiedergibt (wir werden später darauf eingehen). Sie können sicher sein, dass alles wie geplant angezeigt wird.

Ein weiterer ziemlich erstaunlicher Punkt. Flutter unterstützt Plattformen ab iOS 8 und Android API v16. Aus Sicht der Benutzeroberfläche spielt Flutter keine Rolle, welche APIs auf einer bestimmten Plattform verfügbar sind. Er hätte die Möglichkeit, mit Canvas und einer Art Interaktion mit dem Grafiksubsystem zu arbeiten. Dies bedeutet, dass wir die neuesten UI-Elemente von AndroidX beispielsweise auf einem 8 Jahre alten Telefon zeichnen können. Es gibt sicherlich eine Frage der Leistung dieses Ansatzes auf den ältesten unterstützten Plattformen, aber dies ist eine andere Frage.

Native UI-Leistung



Wie Sie sehen können, ähnelt Flatters Ansatz beim Rendern der Benutzeroberfläche eher dem von Hybrid-Apps wie Ionic. Wir haben eine einzige Engine zum Rendern der Benutzeroberfläche auf allen Plattformen. Dies ist die Skia- Grafikbibliothek. Google hat Skia 2005 als Produkt gekauft und daraus ein Open Source-Projekt gemacht. Dies deutet zumindest darauf hin, dass dies ein ziemlich ausgereiftes Produkt ist. Einige Skia-Leistungsmerkmale:

  • Copy-on-Write für grafische Elemente und andere Datentypen
  • Verwenden Sie nach Möglichkeit Stapelspeicher, um die Fragmentierung zu verringern
  • Gewindesicherheit für bessere Parallelisierung

Ich fand keine überzeugenden Skia-Leistungstests im Vergleich zu ähnlichen Bibliotheken (siehe Kairo ), aber einige Tests zeigen einen durchschnittlichen Leistungszuwachs von 50%, außer in bestimmten Situationen. Ja, dies ist nicht besonders wichtig, da diese Tests auf der Verwendung von OpenGL auf Desktops basieren und ...

Skia kann mit vielen GPU-Backends interagieren. Seit kurzemUnter iOS verwendet Flutter seit Version 11 standardmäßig Metal als Backend-GPU. Unter Android ab API 24 - Vulkan. Für Versionen unten - OpenGL. All dies gibt uns einen offensichtlichen Produktivitätsgewinn. Auf anderen "Hardware" -Plattformen verwendet Skia / Flutter meines Wissens OpenGL, was uns im Prinzip nicht daran hindert, Anwendungen mit ausreichender Grafikleistung zu schreiben.

Web steht auseinander. Derzeit liegt das gesamte UI-Rendering noch auf dem Canvas / HTML-Bundle. Daher ist Skia in keiner Weise an diesem Prozess beteiligt. Außerdem interagiert die Dart-VM nicht direkt mit dem DOM. Zuerst kommt die Konvertierung in js. All dies wirkt sich nicht optimal auf die Produktivität aus und ist mit bloßem Auge direkt erkennbar. Doch Arbeit ist im Gange zu implementieren CanvasKitin Flutter, wodurch Skia wiederum in Browsern über WebGL verwendet werden kann.

Schließlich verwenden C # -Programmierer SkiaSharp schon relativ lange - ein Wrapper über Skia für Mono / .Net x. Und die Xamarin-Community verwendet diese Bibliothek, um benutzerdefinierte UI-Elemente zu zeichnen. Dies ist eine sehr beliebte Bibliothek. Wenn dies kein Sieg ist, dann weiß ich nicht, was es ist.

100% ige Fähigkeit, jedes API-Betriebssystem aufzurufen


In Flutter gibt es zwei Prinzipien der Interaktion mit der "Außenwelt":


Mit Plattformkanälen können Sie über ein Messaging-System mit der nativen Laufzeit / API interagieren. Aus architektonischer Sicht kann dies wie folgt gesehen werden. Optisch ist Flutter nur eine Leinwand, die im einzigen Activity / UIViewController Ihrer nativen Anwendung auf Vollbild ausgedehnt wird. Dies ist genau der gleiche Ansatz, den ich für Spieleentwickler (Game Engines) verwende. Jene. Sie können das iOS / Android-Projekt Ihrer Anwendung öffnen und Swift / Kotlin / etc. weitere Funktionen hinzufügen. Das Problem ist, dass die native Laufzeit und die Dart-VM nichts voneinander wissen (zusätzlich zu der Tatsache, dass die native Laufzeit weiß, dass die Anwendung über Canvas verfügt und dort etwas angezeigt wird). Wenn Sie beispielsweise die Datei MainActivity.kt Ihres Android-Projekts öffnen, wird Folgendes angezeigt:

class MainActivity: FlutterActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    GeneratedPluginRegistrant.registerWith(this)
  }
}

Haben Sie bemerkt, dass Ihre Aktivität von FlutterActivity erbt? Dies gibt uns die Möglichkeit, den Mechanismus zum direkten Senden von Nachrichten an Flutter / DartVM zu konfigurieren. Dazu müssen wir die configureFlutterEngine- Methode überschreibenund es wird den Namen der aufgerufenen Methode und den Namen des Kanals zum Senden von asynchronen Nachrichten bestimmen. Alle. Dies ermöglicht es uns, jeden nativen Code zu schreiben und jede native API aufzurufen! Gleichzeitig gibt es bereits eine große Anzahl von Plugins (Paketen), die Sie vor dem Schreiben von nativem Code bewahren. Sie können nur Dart verwenden. Das ist einfach wunderbar! Sie schreiben die Benutzeroberfläche separat und einmal für jede Plattform, verwenden DartVM für die Arbeit mit Benutzeroberfläche, E / A und verwenden als Computerkomponente Plugins, die native Funktionen implementieren und 99% aller Funktionen abdecken. Und wenn dies nicht ausreicht, schreiben Sie nativ und kommunizieren über den Nachrichtenmechanismus. Geschichte.

Der zweite Mechanismus ist eine Fremdfunktionsschnittstelle oder FFI. Dies ist ein ziemlich gebräuchlicher Begriff für den Iteropenmechanismus bei anderen Sprachen, hauptsächlich C. In der .Net-Welt heißt dieser Mechanismus P / Invoke, für die JVM ist es JNI. Kurz gesagt, dies ist die Fähigkeit, mit in C / C ++ / usw. geschriebenen Bibliotheken zu interagieren. Zum Zeitpunkt des .Net Frameworks war beispielsweise keine Software in C # geschrieben, und die überwiegende Mehrheit der Software wurde in C / C ++ geschrieben. Daher war ein Mechanismus erforderlich, um mit diesen Bibliotheken arbeiten zu können. Gleiches gilt für JVM, Python, wie Sie es nennen. FFI wird auf die eine oder andere Weise in allen plattformübergreifenden mobilen Frameworks verwendet. In jüngerer Zeit unterstützt DartVM auch FFI für die Interaktion mit C und JavaScript! Diese Funktion befindet sich zwar in einem Beta-Zweig, steht jedoch bereits zur Verfügung (auf eigene Gefahr und Gefahr).

Wie Sie sehen können, decken Flutter und DartVM 100% der Möglichkeiten auf nativen Plattformen ab und noch mehr.

Leicht zu lernen und sehr ausdrucksstarke Sprache


Ich gebe ehrlich zu, während Dart für mich nicht die beste Sprache der Welt bleibt. Es gibt kein striktes Typsystem, es gibt keine funktionalen Brötchen, wie z. B. Musteranpassungs- oder Unveränderlichkeitsmerkmale (wie sie bald geliefert werden) usw. In Bezug auf das Typsystem wurde Dart ursprünglich als "ohne typische" Sprache konzipiert, ala JS, aber für die normale Unterstützung der AOT-Kompilierung war es dennoch notwendig, das Typsystem auf ein strengeres, wenn auch nicht vollständiges, würde ich sagen. Es ärgert mich immer noch, mit Methodensignaturen zu arbeiten, nämlich mit Argumenten. Alle diese Klammern sind @requiredaus irgendeinem Grund wütend . Aber Dart ist eine sehr leicht zu erlernende Sprache. In der Syntax ist dies für mich eine Kreuzung zwischen Java und JS. Dart vergibt viel, wie JS. Im Allgemeinen ist dies eine ziemlich leicht zu erlernende Sprache, ich habe keine wesentlichen Probleme festgestellt.

Rantime, die gut in das Frontend-Entwicklungsparadigma passt


Lassen Sie uns nun über Dart VM sprechen. Im Allgemeinen enthält Dart VM viele Dinge, von GC bis Profiler und Observatory. Hier möchte ich nur über GC und bedingte Laufzeit sprechen. Sie können sich mit vertraut zu machen , wie die Laufzeit funktioniert und was es aus hier . Ich bin kein Experte auf diesem Gebiet, aber für mich selbst habe ich einige der Vorteile von Dart VM festgestellt, die ich zu beschreiben versuchen werde. Zuvor möchte ich darauf hinweisen, dass Dart und die entsprechende VM ursprünglich als Ersatz für JS entwickelt wurden, was sozusagen auf den Fokus auf die Frontend-Entwicklung hinweist.

Isolate

Dart VM hat das Isolate-Konzept. Isolieren ist eine Kombination aus einem Hauptthread, der direkt auf dem Dartcode ausgeführt wird, und dem isolierten Heap, in dem die Objekte aus dem Dartcode tatsächlich zugeordnet sind. Dies ist eine vereinfachte Struktur. Isolate hat auch Hilfs- / System-Threads, es gibt OS-Threads, die Isolate betreten und verlassen können usw. Der Stapel ist auch in Isolate vorhanden, aber Sie als Benutzer arbeiten nicht daran. Die Hauptsache, die hier hervorgehoben werden muss, ist, dass wenn Sie sich ein Isolat ansehen, dies eine Single-Thread-Umgebung ist. Standardmäßig verwendet Flutter ein Standardisolat. Ähnelt es etwas? Ja, das ist eine JS-Umgebung. Genau wie in JS können Dart-Programmierer nicht mit Multithreading arbeiten. Jemand könnte denken, dass dies ein Durcheinander, eine Vereinfachung und eine Verletzung der Rechte von echten Entwicklern ist, aber ich denke, dass bei der Arbeit mit der BenutzeroberflächeWenn Sie mit einem bedingten DOM arbeiten (und keine Polygone auf dem Bildschirm zeichnen), müssen Sie dies nicht tun. Es ist gefährlich, mit mehreren Threads zu arbeiten.

Hier war ich natürlich schlau, wenn Sie wirklich wollen, dann können Sie das separat gestartete Isolate verwenden, um parallele Aufgaben auszuführen (Hallo WebWorker). Hier können Sie detailliert sehen, wie Sie mit zusätzlichem Isolate in Flutter arbeiten können. Im Allgemeinen wissen Isolate, wie der Name schon sagt, nichts voneinander, halten keine Verbindungen zueinander und kommunizieren über ein Nachrichtensystem.

Zusätzlich zum Single-Thread-Ansatz ist die Tatsache, dass jedem Isolat ein separater Heap zugewiesen wird, ohne dass der Stapel dieses Threads manipuliert werden kann, meiner Meinung nach ein sehr guter Ansatz. Wenn Sie eine Serveranwendung schreiben, die beispielsweise eine große Anzahl von Zeilen bearbeitet, und diese Zeilen in einem Heap gespeichert werden, in dem sie mit enormer Geschwindigkeit angezeigt und ausgeblendet werden, während der Speicher fragmentiert und GC-Jobs hinzugefügt werden, können Sie diese Zeilen oder zumindest einen Teil davon übertragen Heaps auf dem Stack sparen Ressourcen und verbessern die Leistung. Ein Beispiel ist so lala, aber du verstehst mich. Bei der Arbeit mit der Benutzeroberfläche, bei der möglicherweise eine ausreichende Anzahl von Benutzeroberflächenelementen vorhanden ist, die eine kurze Lebensdauer haben können (z. B. Animation), aber gleichzeitig nur ein Client und die Menge der verarbeiteten Daten im Vergleich zur Serveranwendung vernachlässigbar sind.Die Möglichkeit, direkt mit dem Stapel zu arbeiten, ist einfach nicht erforderlich. Ich spreche nicht von Boxen / Unboxen, was in diesem Fall sein könnte und was absolut sinnlos ist. Und es sollte beachtet werden, dass Objekte in Dart VM ziemlich oft zugewiesen werden. Selbst um den doppelten Betrag von der Dart-Methode auszugeben, weist die VM dem Heap separat ein Stück zu. Wie geht der GC mit dieser Last um? Lassen Sie uns einen Blick darauf werfen.

Young Space Scavenger (und Parallel Mark Sweep)

Wie alle GCs hat auch der GC in der Dart VM Generationen. Außerdem kann der GC in der Dart-VM nach dem Arbeitsprinzip in zwei Komponenten unterteilt werden: Young Space Scavenger und Parallel Mark Sweep. Ich werde nicht auf das letzte Prinzip eingehen, dies ist ein ziemlich populäres Prinzip der Speicherbereinigung, das fast überall implementiert ist und Flutter keinen besonderen Vorteil verschafft. Wir interessieren uns für die erste. Das Arbeitsprinzip von Young Space Scavenger ist im folgenden Bild gut dargestellt:


Es zeigt deutlich die Vorteile dieses Ansatzes. Young Space Scavenger arbeitet für die neuesten Objekte im Speicher, wir können das für die erste / Null-Generation von Objekten sagen. Oft, und dies ist charakteristisch für die Flutter / Dart-VM, haben die meisten neuen Objekte eine kurze Lebensdauer. In einer Situation, in der Sie viele Objekte zuweisen, die nicht lange leben, kann der Speicher sehr fragmentiert sein. In diesem Fall müssen Sie entweder Speicher- oder Prozessorzeit bezahlen, um das Problem zu beheben (obwohl Sie das Problem mit solchen Methoden nicht beheben sollten). Young Space Scavenger löst dieses Problem. Wenn Sie sich das Bild oben ansehen, dann gibt es wirklich keinen 6-Schritt. Sie müssen den ersten Speicherblock nicht löschen. Standardmäßig denken wir, dass dieser Block nach dem Kopieren von Objekten in den zweiten leer ist. Nun, wenn Sie überlebende Objekte in den zweiten Block kopieren,Wir setzen sie natürlich einzeln, ohne Fragmentierung zu erzeugen. All dies ermöglicht es VM, viele neue Objekte zu einem relativ niedrigen Preis zuzuweisen.

Leerlaufzeit-GC

Wie Sie verstehen, arbeiten die Teams Flutter und Dart VM eng zusammen, und das Ergebnis dieser Zusammenarbeit kann als Leerlaufzeit-GC betrachtet werden. Wie der Name schon sagt, handelt es sich um eine Speicherbereinigung in dem Moment, in dem nichts passiert. Im Kontext von Flutter in dem Moment, in dem die Anwendung visuell nichts ändert. Es gibt keine Animation, kein Scrollen oder keine Benutzerinteraktion. In diesen Momenten sendet Flutter Nachrichten an die Dart-VM, die jetzt im Prinzip ein guter Zeitpunkt ist, um mit der Speicherbereinigung zu beginnen. Als nächstes entscheidet der Müllsammler, ob er mit seiner Arbeit beginnen soll. Diesbezüglich erfolgt die Speicherbereinigung natürlich für ältere Objekte, die über den Parallel Mark Sweep verwaltet werden. Dies ist an sich ein ziemlich teurer Prozess, und Idle Time GC ist in dieser Hinsicht ein sehr nützlicher Mechanismus.

Es gibt andere Dinge wieGleitverdichtung und komprimierte Zeiger . Der erste ist der Speicherdefragmentierungsmechanismus nach dem Ausführen von Parallel Mark Sweep. Dies ist auch ein teurer Prozess und funktioniert nur, wenn Leerlaufzeit vorhanden ist. Der zweite Ansatz, Compressed Pointers (Komprimierte Zeiger), komprimiert 64-Bit-Zeiger auf 32 Bit, wodurch Speicherplatz gespart wird (ich denke, dies ist in einer Serverumgebung viel nützlicher als in einer mobilen).

Zusammenfassung


Wenn Sie bis zu dieser Zeile lesen, dann erstens Glückwunsch und zweitens muss ich sagen, dass ich keine Erfahrung mit dem Schreiben von Artikeln habe. Daher verstehe ich nicht ganz, ob ich es geschafft habe, meinen Standpunkt zu vermitteln. Und die Idee ist einfach: Wenn Sie eine mobile Anwendung mit Flutter schreiben, stellt sich heraus, dass sie nativ ist. Und in Form eines Bonus erhalten Sie eine sehr anständige Anwendungsentwicklungsgeschwindigkeit. Hot Reload / Restart ist in der Frontend-Entwicklung einfach unverzichtbar. Können Sie sich einen Schriftsetzer vorstellen, der beispielsweise bei jedem Farbwechsel einer Schaltfläche das gesamte Projekt für jeden Browser erstellen / kompilieren müsste? Natürlich nicht. Im Allgemeinen verdient Hot Reload / Restart einen separaten Artikel. Aber ich war abgelenkt.

Meine Erfahrung mit Flutter zeigt mir, dass dieser Rahmen in naher Zukunft dominieren wird. In regelmäßigen Abständen führe ich Interviews für eine Position als Flutter-Entwickler durch, und in der Hälfte der Fälle haben Unternehmen, die einen Flutter-Entwickler suchen, Mitarbeiter mobiler nativer Entwickler. Sie haben Flutter gerade bei Innen- / Nebenprojekten ausprobiert, waren zufrieden / begeistert und wechselten langsam zu Flutter. Dies ist ein echter Sieg, scheint mir. Was über Xamarin leider nicht gesagt werden kann. Sehr oft ist die Entscheidung für Xamarin einfach darauf zurückzuführen, dass der Rest des Stapels in .Net geschrieben ist und dies eine rutschige Steigung ist.

Zusammenfassend möchte ich sagen, dass Sie sich Flutter ansehen sollten, wenn Sie überlegen, welche Seite Sie bei der Entwicklung Ihrer neuen mobilen Anwendung ansprechen sollten.

All Articles