Alle rieten uns zu Electron. Einmal schreiben, überall laufen lassen. Schnell vorankommen. Wir haben das Gegenteil getan – SwiftUI bei Apple, Jetpack Compose auf Android, C++/WinRT unter Windows, rohes Metal und Vulkan dort, wo wir Pixel auf die Uhr brauchten. Das haben wir beim Bau von vier nativen Clients für ein Produkt gelernt.
Der einfache Weg vs. der richtige Weg
Wenn Sie erzählen, dass Sie 2024 eine Remote-Desktop-App von Grund auf bauen, lautet die erste Frage immer: „Warum nicht einfach Electron?“
Es ist eine berechtigte Frage. Electron treibt einige der erfolgreichsten Apps der Welt an – VS Code, Slack, Discord, den Desktop-Wrapper von Figma. Man schreibt einmal und liefert überall aus. Aus Webentwicklern werden über Nacht Desktop-Entwickler. Der Vorteil bei der Markteinführungszeit ist real.
Wir haben uns die Zahlen angesehen, die Abwägungen bedacht und den denkbar schwersten Weg gewählt: vollständig nativ auf jeder Plattform. SwiftUI auf iOS und macOS. Jetpack Compose auf Android. C++/WinRT unter Windows. Metal für das Rendering bei Apple. Vulkan überall sonst. Ein eigener Go-Server im Kern.
Nicht, weil wir Leiden genießen, auch wenn es sich an manchen Tagen so anfühlt. Sondern weil Nativität bei dieser Art von App kein Luxus ist. Sie ist eine Voraussetzung.
Die Electron-Steuer ist real
Fangen wir damit an, was Electron eigentlich ist: ein Chromium-Browserfenster, das so tut, als wäre es eine Desktop-App. Das ist keine Kritik – es ist Architektur. Und für viele Anwendungen völlig in Ordnung.
Aber bei einem Remote Desktop? Sie streamen Pixel von einem anderen Computer und rendern sie in Echtzeit, während Sie jedes Eingabeereignis erfassen und zurücksenden. Latenz ist kein Nice-to-have. Sie ist das ganze Produkt.
Das haben wir gemessen, als wir beide Ansätze als Prototyp gebaut haben:
- Arbeitsspeicher – Nativer Client im Dauerbetrieb: ~45 MB. Electron-Prototyp: ~380 MB. Ein Unterschied um das 8,4-Fache im Leerlauf, bevor eine der Apps auch nur ein einziges Frame dekodiert.
- Kaltstart – Die native macOS-App startet kalt in unter 200 ms. Der Electron-Prototyp brauchte 2 bis 3 Sekunden. Bei einem Werkzeug, das Sie zwanzigmal am Tag starten, summiert sich das zu echter Reibung.
- Akku – Auf einem Mac im Akkubetrieb zog der Electron-Build bei einer Verbindung im Leerlauf etwa das Dreifache an Leistung. Chromium schläft nicht billig.
Die 380 MB sind nicht Electron, das aufgebläht ist. Es ist Chromium, das seine Arbeit macht – V8, ein GPU-Prozess, Hilfsprozesse, eine ganze Browser-Engine. Das ist beeindruckende Ingenieurskunst. Nur ist es Ingenieurskunst für ein anderes Problem.
Frames zählen mehr als Funktionen
Remote Desktop ist eine der wenigen App-Kategorien, in denen jedes einzelne Frame zählt. Verlieren Sie ein Frame, spürt der Nutzer es. Fügen Sie 16 ms Eingabelatenz hinzu, kann eine Designerin keine glatten Kurven mehr zeichnen. Fügen Sie 32 ms hinzu, kann ein Spieler nicht mehr spielen.
Mit nativem Rendering sprechen wir direkt mit der GPU. Auf Apple-Plattformen gibt uns VideoToolbox direkten Zugriff auf Hardware-Videodekodierung. Wir nehmen ein H.265-Frame aus dem Netzwerk, dekodieren es in Hardware und zeigen es an – ohne dass das Frame je den Hauptspeicher berührt. Die Pipeline vom Dekodieren zur Anzeige läuft auf einem modernen Mac in unter 4 ms.
In Electron wandert dasselbe Frame durch den Compositor von Chromium, über die IPC-Brücke, wird von Skia gemalt und dann vom Betriebssystem erneut zusammengesetzt. Jeder Hop fügt Latenz hinzu. Jeder Hop fügt Jitter hinzu. Und Jitter – uneinheitliches Frame-Timing – ist es, was Remote Desktop unstimmig wirken lässt, selbst wenn die durchschnittliche FPS in Ordnung aussieht.
Wir haben nativ nicht gewählt, um Puristen zu sein. Wir haben es gewählt, weil die Physik unseres Problems es verlangte – etwa 8 ms Verarbeitung im LAN (der Rest ist die Bildwiederholrate Ihres Displays mit 60 Hz) lassen keinen Platz für einen Browser dazwischen.
Hauptbuch der Fähigkeiten: nativ vs. Web
Die Debatte Electron gegen nativ bleibt oft im Bauchgefühl stecken. Also haben wir die sieben Betriebssystemfähigkeiten aufgeschrieben, auf die Remio in jeder Sekunde jeder Sitzung angewiesen ist, und schlicht gefragt: Wie schlägt sich jede unter jeder Laufzeitumgebung?
| Fähigkeit | Nativ | Web / Electron |
|---|---|---|
| 60-fps-Hardware-Decoding | ● Direkt über VideoToolbox / D3D11VA | ○ Über WebCodecs, Jitter |
| USB-Audio mit niedriger Latenz | ● CoreAudio / WASAPI | — In der Sandbox, 40 ms+ |
| Überwachung der Tastatureingabe | ● CGEvent / SendInput | — Außerhalb des Fokus blockiert |
| GPU-Zugriff über Metal / D3D11 | ● Zero-Copy-Texturen | ○ WebGPU, Kopier-Hops |
| Lokales Dateisystem | ● Vollständig, vom Betriebssystem begrenzt | ○ Nur Auswahldialog, Rückfragen |
| Mehrere Fenster, mehrere Displays | ● Native Fensterverwaltung des Betriebssystems | ○ BrowserWindow-Shims |
| Dauerbetrieb im Hintergrund | ● LaunchAgent / Dienst | — Beim Ausblenden angehalten |
Jede Zeile ist eine Funktion, die wir heute ausliefern. Jedes „—“ in der Web-Spalte ist ein Workaround, den wir erfinden, dokumentieren und für den wir uns entschuldigen müssten. Nativ zu gehen heißt, diese Fähigkeiten als Grundbausteine zu behandeln statt als Polyfills.
Bürgerrecht auf der Plattform
Hier ist etwas, wovon die Einmal-schreiben-überall-laufen-Fraktion selten spricht: Nutzer merken es.
Sie merken es, wenn eine App die Übergänge des System-Dunkelmodus nicht respektiert. Wenn sich die Scroll-Physik leicht falsch anfühlt. Wenn die App nicht in Spotlight auftaucht oder die macOS-Fensterverwaltung nicht richtig behandelt. Wenn das Kontextmenü wie eine Webseite aussieht statt wie ein natives Menü.
Das sind keine Nice-to-haves. Sie sind der Unterschied zwischen einer App, die Menschen dulden, und einer App, die Menschen lieben. Unter iOS ist das besonders kritisch – die App-Store-Prüfung lehnt Apps ab, die sich nicht nativ anfühlen, und das zu Recht.
Mit SwiftUI bekommen wir all das geschenkt. Dynamic Type, VoiceOver-Bedienungshilfen, System-Haptik, Multitasking auf dem iPad, Tastaturkürzel auf dem Mac. Wir implementieren keine Plattformfunktionen neu. Wir nutzen sie.
Auch die Kosten sind real
Seien wir ehrlich über die Kehrseite: Nativ zu gehen ist teuer. Nicht in Euro – in Zeit und Komplexität.
Wir pflegen vier UI-Codebasen. Unsere Netzwerk- und Codec-Schicht ist geteilt (Go für das Signaling, C++ für das Streaming-Protokoll), aber jedes Pixel, das Sie auf dem Bildschirm sehen, ist plattformspezifischer Code. Eine Funktion, die in Electron einen Tag dauert, dauert bei uns drei bis fünf Tage, weil wir sie viermal bauen, jeweils für die Plattform abgestimmt.
Wir hatten Wochen, in denen eine einzelne Animation unter iOS wunderbar lief, auf Android kaputt war und unter Windows ruckelte. Die Debugging-Matrix ist brutal.
Aber das haben wir gelernt: Der schwerste Weg und der richtige Weg sind oft derselbe Weg. Unsere Nutzer kennen unsere Architektur nicht und interessieren sich nicht dafür. Sie wissen, dass sich Remio schnell anfühlt, richtig anfühlt und ihren Akku nicht zum Frühstück verschlingt.
Würden wir es wieder tun
Ohne zu zögern.
Der native Ansatz hat uns Leistung gegeben, die Electron für diesen Anwendungsfall grundsätzlich nicht erreichen kann. Er hat uns Apps gegeben, die sich auf jeder Plattform zugehörig anfühlen. Er hat uns einen Speicherbedarf unter 45 MB statt 380 MB gegeben. Er hat uns etwa 8 ms Verarbeitung im LAN gegeben (der Rest ist die Bildwiederholrate Ihres Displays mit 60 Hz), wo ein in einen Browser verpackter Wettbewerber jenseits von 60 ms liegt.
Vor allem hat er uns einen technischen Burggraben gegeben. Nativ auf vier Plattformen zu bauen ist so schwer, dass die meisten Wettbewerber es nicht tun werden. Diese Schwierigkeit ist unser Vorteil.
Die Kategorie Remote Desktop wurde von in Electron verpackten Web-Apps und veralteten nativen Apps beherrscht, die seit Jahren nicht mehr wesentlich aktualisiert wurden. Es gibt Platz für etwas, das zugleich modern und nativ ist – von Grund auf gebaut mit der heutigen Hardware im Blick.
Das ist Remio. Auf die harte Tour gebaut, weil manche Dinge es wert sind, richtig gemacht zu werden.