
Warum wir unsere Flutter-App verworfen und Cliqer Remote nativ auf einem Rust-Kern neu gebaut haben

Am 26. September haben wir begonnen, Cliqer Remote, unsere Smartphone-App für Vortragende, in Flutter zu entwickeln. Fünf Tage später war sie auf TestFlight und im internen Track von Google Play, mit allen Funktionen der Web-App für Vortragende: Presenter, Live-Bildschirm, Annotationen, Chat, Notizen und Anrufe. Sie funktionierte. Dann haben wir sie auf echten Smartphones gemessen, zugesehen, wie eines davon allein beim Anzeigen eines geteilten Bildschirms eine Oberflächentemperatur von 42 °C erreichte, und sie verworfen.
Außerhalb unseres Teams hat diese App nie jemand gesehen. Stattdessen erhalten Sie eine native App auf jeder Plattform: SwiftUI auf iPhone, iPad und Apple Watch, Kotlin und Jetpack Compose auf Android und Wear OS, und darunter eine einzige Engine, einmal in Rust geschrieben. Dies ist die Geschichte, warum, mit den Zahlen, die wir unterwegs gemessen haben.
- Ein Presenter auf dem Smartphone hat eine ungewöhnliche Aufgabe für eine App: eine Stunde lang in einer warmen Hand liegen, Live-Video des Bildschirms zeigen und nie einen Tipp verpassen. Frame-Zeit, Wärme und Größe zählen hier mehr als bei den meisten Apps.
- Unser Flutter-Build war schnell geschrieben und sah gut aus, aber seine Glaseffekte und sein Videopfad kosteten die GPU bei jedem Frame. Auf einem Galaxy S24+ haben wir die GPU-Arbeit eines Bildschirms von 19,8 ms auf 5,7 ms pro Frame gesenkt und kämpften trotzdem weiter gegen die Engine, statt das Produkt zu bauen.
- Dann haben wir drei Builds auf dasselbe Smartphone gespielt, im selben Raum, jeweils zehn Minuten lang mit demselben bewegten Bildschirm. Der erste Flutter-Build zeichnete 47,6 Frames pro Sekunde, erwärmte das Smartphone um 5,9 °C und verbrauchte 168 mAh. Die native App zeichnete überhaupt keine UI-Frames, erwärmte es um 0,2 °C und verbrauchte 86 mAh: die Hälfte des Akkus.
- Die nativen Apps sind kleiner: 10,8 MB für die iPhone-App samt enthaltener Apple Watch App (die Flutter-Version hatte 27,6 MB) und ein Android-Download von 5,8 MB (Flutter: 15,6 MB), auf dieselbe Weise gemessen.
- Im selben Zug haben wir die Desktop-App einen Klick zehnmal schneller in einen Folienwechsel umsetzen lassen: 48 ms in PowerPoint und 42 ms in Keynote auf einem Mac, wo es vorher etwa eine halbe Sekunde dauerte.

Ein Presenter ist eine ungewöhnliche App
Die meisten Apps werden nur kurz genutzt. Ein Presenter nicht. Er liegt einen ganzen Vortrag lang in einer Hand, oft unter Bühnenlicht, mit eingeschaltetem Display und durchgehend aktivem Funk. Bei Cliqer zeigt er außerdem ein Live-Bild vom Bildschirm der vortragenden Person, zeichnet Annotationen auf die Folien, überträgt Chat und Notizen und kann die vortragende Person vor die Kamera holen, wenn der Host sie einlädt.
Aus dieser Aufgabe ergeben sich drei Regeln:
- Jeder Tipp muss ankommen, sofort. Ein Klick, der zu spät ankommt, bedeutet Vortragende, die schweigend vor dem Publikum stehen.
- Das Smartphone muss kühl bleiben. Ein heißes Smartphone drosselt sich, und ein gedrosseltes Smartphone verliert Frames, dekodiert Video zu spät und leert seinen Akku schneller. Außerdem ist es unangenehm, es eine Stunde lang zu halten.
- Die App muss klein sein und schnell starten. Viele installieren sie erst am Veranstaltungsort, oft im Konferenz-WLAN, Minuten bevor sie auf die Bühne gehen.
Für die meisten Apps erfüllt Flutter alle drei Regeln. Unsere App erwies sich als die Art von App, bei der es mehr kostet, als es bringt.
Was Flutter richtig gemacht hat
Ehre, wem Ehre gebührt. Flutter hat uns in fünf Tagen von einem leeren Ordner zu einer voll ausgestatteten App in beiden Stores gebracht, mit einer einzigen Codebasis, Hot Reload, hervorragender Testunterstützung und einer Oberfläche, die überall gleich aussah. Wir haben 266 Tests dafür geschrieben. Wenn Sie eine App mit Formularen und Listen, ein Dashboard oder einen Shop bauen, würden wir es weiterhin ohne zu zögern empfehlen.
Wir haben auch viel daraus gelernt. Fast jede Erkenntnis in diesem Beitrag stammt aus Traces dieses Flutter-Builds auf einem echten Smartphone, und einige der Korrekturen stecken heute in jedem Cliqer-Client, auch im Web.
Wo es wehtat: Glas kostet pro Frame einen ganzen Bildschirm
Der Look von Cliqer ist Milchglas: durchscheinende Panels, die weichzeichnen, was hinter ihnen liegt. Auf iPhone und iPad war das günstig. Auf unserem Android-Testgerät, einem Galaxy S24+ mit 120-Hz-Display, nicht. Bei 120 Hz bleiben für einen Frame 8,3 ms, für alles.
Wir haben die GPU direkt auf dem Gerät per Trace analysiert und die Ursache darin gefunden, wie die Rendering-Engine den Hintergrund ausliest: Jedes Glaspanel kopierte bei jedem Frame den gesamten Bildschirm, zusätzlich mit Multisampling. Der Beitrittsbildschirm hatte neun Glaspanels, also neun Vollbildkopien pro Frame. Die GPU in diesem Smartphone ist ein Design der Desktop-Klasse und kein Tiler: Sie hat keine günstige Möglichkeit, das gerade Gezeichnete zurückzulesen, und jede neue Texturgröße bedeutete eine frische Speicherzuweisung, die der Kernel zuerst mit Nullen füllt. In einem Trace entfielen 71 % der Zeit des Raster-Threads auf die Zuweisung von Grafikspeicher.

Wir haben es Bildschirm für Bildschirm behoben. Wir sind auf eine Vorabversion der Engine umgestiegen, damit sich ein Blur auf sein Panel begrenzen ließ (41 ms auf 17 ms). Wir haben die neun Panels auf dem Beitrittsbildschirm zu einem gemeinsamen Lesevorgang zusammengefasst (19,8 ms auf 5,7 ms). Wir haben aufgehört, die Größe von Glasflächen zu animieren, weil jede neue Größe eine neue Zuweisung bedeutete, und die Animationen stattdessen mit Ebenen fester Größe nachgebildet. Der schlechteste Frame des QR-Scanners sank von 285 ms auf 18 ms.
Jede dieser Korrekturen war ein Workaround für die Engine, keine Funktion für Vortragende. Und da Glas 80 bis 90 % der GPU-Zeit in einem Raum ausmachte, waren wir immer nur ein neues Panel davon entfernt, wieder Frames zu verlieren.
Wo es richtig wehtat: Video und die Wärme, die es erzeugt
Der geteilte Bildschirm ist das Aufwendigste, was die App anzeigt. Im Flutter-Build wurde jedes dekodierte Videoframe als Textur an die UI übergeben, was bedeutete, dass sich die UI für jedes Videoframe neu zeichnete: der Raum, das Glas, die Bedienelemente, alles, 45-mal pro Sekunde, nur um die Pixel in einem einzigen Rechteck zu bewegen.
Wir haben das erstmals am 1. Oktober auf dem Galaxy mit System-Traces gemessen. Während das Video lief, lag die GPU bei etwa 440 MHz. Bei einem Folienwechsel dauerten Frames 25 bis 33 ms, und die GPU erreichte für mehr als die Hälfte des Übergangs ihre Obergrenze von 800 MHz. Das Smartphone befand sich im thermischen Systemstatus „moderate“ mit einer Oberflächentemperatur von 42 °C und drosselte seine eigene GPU, um damit klarzukommen. Die Wärme verfälschte auch unsere Messungen: Ein warmes Smartphone maß etwa 20 % langsamer als ein kühles, also mussten wir bei jedem Vergleich die Builds bei gleicher Temperatur abwechseln.
Dann haben wir das naheliegende Experiment versucht: das Video auf eine native Ebene legen, die das Betriebssystem selbst zusammensetzt, außerhalb der UI. Gleiches Smartphone, gleiche App, gleicher Raum: Die UI zeichnete sich für das Video nicht mehr neu, der GPU-Takt fiel von 440 auf 121 MHz, und der Frame bei einem Folienwechsel sank von 25 bis 33 ms auf 3 bis 7 ms. Wir haben diese Korrektur am 1. Oktober in der Flutter-App ausgeliefert. Sie zeigte uns auch, wo die eigentliche Antwort lag: In einer nativen App liegt Video immer auf einer Systemebene, auf dem iPhone wie auf Android, sodass diese ganze Klasse von Problemen von vornherein verschwindet, statt per Workaround.
Gleiches Smartphone, gleicher Raum, zehn Minuten
Behauptungen über Wärme sind billig, also haben wir gemessen. Am 5. Oktober haben wir drei Builds nacheinander auf dasselbe Galaxy S24+ gespielt, jeweils zehn Minuten lang, ohne Ladekabel, im selben Raum, mit demselben bewegten geteilten Bildschirm. Vor jedem Durchlauf kühlte das Smartphone wieder ab.
- Flutter, erster Build: die App, wie wir sie ursprünglich gebaut hatten, Video von der UI gezeichnet.
- Flutter, optimiert: dieselbe App nach den oben beschriebenen Glas- und Video-Korrekturen.
- Nativ: das neue Cliqer Remote.

Der erste Flutter-Build zeichnete seine gesamte Oberfläche 47,6-mal pro Sekunde neu, nur um ein Video zu zeigen, hielt die GPU im Schnitt bei 366 MHz und verbrauchte 1,47 Sekunden CPU-Zeit pro Sekunde. Die native App zeichnete in zehn Minuten keinen einzigen Oberflächen-Frame: Nur die Videoebene bewegte sich. Ihre GPU lag im Schnitt bei 129 MHz, ihre CPU bei 0,69 Sekunden pro Sekunde, und sie verbrauchte 86 mAh Akku gegenüber 168 mAh. Das ist der halbe Akkuverbrauch für dieselbe Aufgabe.

Und die Wärme. In zehn Minuten trieb der erste Flutter-Build den Akku von 36,2 °C auf 42,1 °C, und das Smartphone begann, sich selbst zu drosseln. Beim optimierten Flutter-Build stieg die Temperatur um 1,9 °C. Bei der nativen App um 0,2 °C. Ein Vortrag dauert länger als zehn Minuten, und genau diesen Unterschied spüren Sie in der Hand.
Fairerweise zum optimierten Flutter-Build: Er kam nah heran. Unsere eigenen Korrekturen in Flutter haben den Großteil der Kosten beseitigt, und nativ schlug ihn mit geringerem Abstand, 12 % weniger CPU und 25 % weniger Akku. Entscheidend ist, wo jede Variante startet. Der erste Build war das, was eine gute Flutter-App ab Werk ist; nativ erreicht das kühle Ergebnis ohne Workarounds.
So haben wir gemessen, damit Sie es nachvollziehen können: Perfetto-Traces auf dem Gerät (Frame-Timeline, GPU-Frequenz, Akkuzähler), Prozess-CPU-Zeit aus dem Kernel und die Akkutemperatur des Smartphones selbst, bei jedem Durchlauf mit derselben 60-fps-Animation auf dem geteilten Bildschirm. Ein Smartphone und ein Durchlauf pro Build: Betrachten Sie die Zahlen also als sorgfältigen Praxistest, nicht als Labor-Benchmark. Der native Durchlauf startete außerdem etwa 2 °C kühler, weshalb wir den Anstieg vergleichen.
Was wir stattdessen gebaut haben
Das neue Cliqer Remote ist auf jeder Plattform nativ, aufgebaut auf einer gemeinsamen Engine.
Die Oberfläche ist auf jeder Plattform nativ. Auf iPhone und iPad ist es SwiftUI mit dem systemeigenen Liquid Glass. Auf Android ist es Jetpack Compose, mit echtem Backdrop-Blur, wo die Plattform es zulässt. Die Apps für Apple Watch und Wear OS sind ebenfalls nativ und klein genug, um Weiter und Zurück an Ihr Handgelenk zu bringen.
Die Engine ist einmal geschrieben, in Rust. Einem Raum beitreten, nach einem Netzwechsel neu verbinden und fortsetzen, das Bildschirmvideo empfangen, Klicks, Laser und Annotationen senden, Chat, Notizen, der Timer, Anrufe und das Koppeln eines Smartphones mit einem Computer: All das steckt in einer Rust-Bibliothek, die sich beide Apps teilen. Jede App zeichnet nur die Oberfläche, dekodiert Video mit dem Hardware-Decoder des Systems und spricht mit Kamera und Mikrofon. Eine Protokollkorrektur landet einmal und erscheint auf beiden Plattformen, und die beiden Apps können nicht auseinanderdriften.
Rust war die naheliegende Wahl für diese Engine: kein Garbage Collector, der einen Frame anhält, Speichersicherheit ohne Laufzeitumgebung, und es kompiliert zu einer kleinen Bibliothek für iOS und Android. Es ist schnell, wo es darauf ankommt. Auf einem Mac paketiert unsere Engine einen 20-KB-H.264-Frame in 31 µs, schließt einen sicheren Handshake in 198 µs pro Seite ab und übergibt in unseren Tests einen 100-KB-Videoframe in 46 µs an die Android-Oberfläche (vor der Optimierung dieser Schnittstelle waren es 440 µs). Über ein Relay dauerte ein Round Trip in unseren Tests im Median 13 bis 16 ms.
Und kleiner

Wir haben beide Builds auf dieselbe Weise gemessen. Die iPhone-App, wie sie bei Apple hochgeladen wird, schrumpfte von 27,6 MB auf 10,8 MB, und das mit der enthaltenen Apple Watch App (1,5 MB). Der Download für ein Android-Smartphone, gemessen mit Googles eigenem Bundletool für dasselbe 64-Bit-Smartphone, sank von 15,6 MB auf 5,8 MB. Rund ein Drittel der alten Größe macht einen Unterschied, wenn jemand die App fünf Minuten vor dem Auftritt im WLAN des Veranstaltungsorts installiert.
Die Jagd nach Millisekunden endete nicht am Smartphone
Eine schnellere Smartphone-App ist nur die Hälfte eines Klicks. Die andere Hälfte ist der Computer, auf dem die Präsentation läuft, und während die Apps neu gebaut wurden, haben wir uns auch diese Seite vorgenommen.
Klicks: von einer halben Sekunde auf ein Zehntel
Wenn ein Klick die Cliqer Desktop-App erreicht, muss sie die Präsentation weiterschalten und dann allen im Raum mitteilen, welche Folie gerade angezeigt wird. Für diesen zweiten Teil fragte sie früher nach jedem Klick die Präsentationssoftware nach der Foliennummer, und diese Abfrage war langsam.

Cliqer 2.3 hält eine Verbindung zu PowerPoint oder Keynote offen und liest die Position direkt aus dem gerade ausgeführten Schritt. Auf einem Mac sank der Median von Klick bis Folienwechsel über 20 Durchläufe von 509 ms auf 48 ms in PowerPoint und von 408 ms auf 42 ms in Keynote. Zehn schnelle Tastendrücke, wie sie Vortragende zum Überspringen eines Abschnitts machen, brauchten früher 5,3 Sekunden, bis alles zur Ruhe kam. Heute werden sie zu einer einzigen Bewegung zusammengefasst und landen in 254 ms.
Video, das auch bei schlechtem WLAN mithält
Anfang dieses Jahres haben wir herausgefunden, warum ein geteilter Bildschirm im WLAN sekundenlang einfrieren konnte. Bildschirmvideo läuft bei Cliqer über einen zuverlässigen Datenkanal, und der Standard, auf dem dieser Kanal aufbaut, wartet mindestens eine volle Sekunde, bevor er ein verlorenes Paket erneut sendet, und verdoppelt diese Zeit bei jeder Wiederholung. Chrome verwendet 400 ms. Jeder Frame hinter dem verlorenen stand in der Warteschlange, der Host schob dann eine vollständige Aktualisierung in genau diese Warteschlange, und bei einer langsamen Verbindung passierte das immer wieder.

Wir haben die Timer für erneutes Senden auf die Werte von Chrome abgestimmt und verhindert, dass sich Aktualisierungen hinter dem Rückstau einreihen. In einer Netzwerksimulation mit einem WLAN-Verlustmodell sank eine 1080p-Freigabe von 15 bis 22 Freezes von einer Sekunde oder länger alle zwei Minuten auf 0 bis 2, und die mediane Verzögerung gegenüber live von bis zu 2,3 Sekunden auf 12 ms. Außerdem haben wir vollständige Aktualisierungen auf eine pro Stream und halbe Sekunde begrenzt, weil jede davon an jeden Zuschauer geht: Vor dieser Begrenzung konnte ein Zuschauer 19 vollständige Aktualisierungen pro Sekunde erhalten, etwa 40 Mbit/s.
Auf der Smartphone-Seite hielt der Hardware-Videodecoder des Galaxy ungefähr einmal pro Sekunde einen gewöhnlichen Frame etwa 60 ms zurück. Den Decoder anzuweisen, mit voller Geschwindigkeit zu laufen, brachte das auf null verspätete Frames in 50 Sekunden. Diese Korrektur steckt in der nativen Android-App.
Was wir einem anderen Team raten würden
Wenn Sie irgendetwas in Echtzeit auf Smartphones bauen: Diese Lektionen haben uns Tage gekostet und lassen sich in Minuten umsetzen:
- Messen Sie auf Ihrem schlechtesten echten Gerät, nicht im Emulator. Unser Emulator lief mit 60 Hz auf einem anderen Grafik-Backend und konnte kein einziges der Glasprobleme zeigen.
- Wechseln Sie die Builds bei gleicher Temperatur ab. Ein warmes Smartphone maß etwa 20 % langsamer. Ein Vergleich zwischen einem kalten und einem heißen Durchlauf führt Sie in die Irre.
- Zählen Sie Ihre Blur-Lesevorgänge. Jeder Backdrop-Blur kann pro Frame eine Vollbildkopie kosten. Fassen Sie sie zusammen, begrenzen Sie sie und animieren Sie nie die Größe einer weichgezeichneten Fläche.
- Zeichnen Sie Ihre UI nie für Video neu. Legen Sie Video auf eine Ebene, die das System zusammensetzt. Das war der größte einzelne Gewinn bei GPU, Akku und Wärme, den wir gemessen haben.
- Fordern Sie vom Hardware-Decoder Echtzeitgeschwindigkeit an. Setzen Sie auf Android die Operating Rate des Decoders. Eine Zeile beseitigte einen 60-ms-Hänger pro Sekunde.
- Prüfen Sie die Timer Ihres Transports. Zuverlässige Datenkanäle erben Timer für erneutes Senden von älteren Standards. Ein Minimum von einer Sekunde ist für Live-Video eine Ewigkeit.
- Behandeln Sie vollständige Aktualisierungen als die teuren Frames, die sie sind. Begrenzen Sie sie pro Stream, denn jede geht an jeden Zuschauer.
- Fassen Sie Eingabe-Bursts zusammen. Zehn Tastendrücke sollten eine Bewegung um zehn sein, nicht zehn Round Trips.
- Lesen Sie, was Ihre Tools in Ihren Build schreiben. Eine Vorabversion der Toolchain hat ungefragt ein Rendering-Flag in unserem Android-Manifest aktiviert.
Was das für Sie bedeutet
10x
schnellerer Klick bis Folienwechsel in PowerPoint und Keynote auf einem Mac
5.8 MB
Android-Download, etwa ein Drittel der alten Größe
10.8 MB
iPhone-App mit enthaltener Apple Watch App
Half
des Akkuverbrauchs unseres ersten Flutter-Builds, gleiches Smartphone, gleiche 10 Minuten
Cliqer Remote ist nativ auf iPhone, iPad, Android, Apple Watch und Wear OS. Klicks sind schneller, das Smartphone bleibt kühl und verbraucht halb so viel Akku wie mit unserem ersten Build, das Video wird so gezeichnet, wie das Smartphone es vorsieht, und die App hat etwa ein Drittel ihrer alten Größe. Die Web-App für Vortragende funktioniert weiterhin in jedem Browser ganz ohne Installation, sodass niemand in Ihrem Raum je außen vor bleibt.
Presenter-Latenz: Warum Millisekunden zählen
Was zwischen einem Tipp und dem Folienwechsel wirklich passiert.
FAQ
Cliqer Remote zeigt Live-Video, Milchglas und einen Presenter auf einem Smartphone, das eine Stunde lang in der Hand der vortragenden Person liegt. Im Flutter-Build zeichnete sich die UI für jedes Videoframe neu, und jedes Glaspanel kopierte bei jedem Frame den gesamten Bildschirm, was auf Android GPU-Zeit und Wärme kostete. Native Apps zeichnen Video von vornherein auf einer Systemebene, und ihr Download ist nur etwa ein Drittel so groß.
In unserem Test auf einem Galaxy S24+ erwärmten zehn Minuten Live-Bildschirmvideo das Smartphone mit der nativen App um 0,2 °C, gegenüber 5,9 °C mit unserem ersten Flutter-Build. Die native App zeichnete während der Videowiedergabe keine Oberflächen-Frames und verbrauchte 86 mAh Akku gegenüber 168 mAh.
Nein. Mit Flutter hatten wir in fünf Tagen eine vollständige App in beiden Stores, und nach unserer Optimierung verbrauchte die native App nur 25 % weniger Akku. Für die meisten Apps ist es eine ausgezeichnete Wahl. Unsere App kombiniert durchgehendes Live-Video, viele weichgezeichnete Glasflächen und lange Sitzungen auf einem warmen Smartphone, und genau in diesem Fall hat uns sein Rendering-Modell am meisten gekostet.
Er übernimmt alles, was nicht gezeichnet wird: einem Raum beitreten und sich neu verbinden, den geteilten Bildschirm empfangen, Klicks, Laser und Annotationen senden, Chat, Notizen, den Timer, Anrufe und das Koppeln eines Smartphones mit einem Computer. Die iPhone- und die Android-App teilen ihn, sodass eine Korrektur auf beiden gleichzeitig ankommt.
Auf einem Mac mit Cliqer 2.3 setzt die Desktop-App einen Klick im Median in 48 ms in PowerPoint und 42 ms in Keynote in einen Folienwechsel um, gemessen über 20 Durchläufe. Das Netzwerk fügt seinen eigenen Round Trip hinzu, der in unseren Relay-Tests im Median 13 bis 16 ms betrug.
Nein. Die Web-App für Vortragende funktioniert in jedem modernen Browser ohne Installation. Die Apps bieten zusätzlich einen nativen QR-Scanner, Face ID oder Biometrie zur Steuerung des Hosts, einen Bildschirm, der wach bleibt, sowie die Presenter für Apple Watch und Wear OS.
Warum wir die Echtzeit-Infrastruktur von Cliqer von Cloudflare weggeholt haben (und warum wir trotzdem Fans bleiben)
Vier Monate auf Cloudflares Edge: was kaputtging, was wir als Workaround gebaut haben und warum Cliqer jetzt auf unseren eigenen dedizierten Servern läuft.
Präsentation vom Smartphone steuern: alle Apps im Vergleich
PowerPoint, Keynote, Canva, Unified Remote, PPTControl, Cliqer und mehr: Welche Smartphone-Fernbedienungen über das Internet funktionieren, Notizen zeigen und zu Ihnen passen.
Leiten Sie Ihre nächste Show mit Cliqer
Weiterlesen
Mehr Produktneuigkeiten für Ihre nächste Show


Warum wir die Echtzeit-Infrastruktur von Cliqer von Cloudflare weggeholt haben (und warum wir trotzdem Fans bleiben)

Wie wir die Bildschirmfreigabe viermal schneller gemacht haben
Den nächsten Ratgeber erhalten, noch vor Ihrer nächsten Show
Praxisnahe Ratgeber für Vortragende, AV-Teams und Eventteams, dazu die Cliqer Releases, auf die es ankommt. Kein Spam, Abmeldung mit einem Klick.