Dossier

L’ingénierie UI à l’heure de l’IA

Avant l’IA, le Web multiplateforme apportait une bonne réponse. Écrire du code coûte désormais moins cher, mais le vérifier reste coûteux. Les UI sur GPU et la génération d’applications natives pour chaque plateforme ont toutes deux une carte à jouer. Nous avons testé 10 frameworks.

OriginalReproduction interdite sans autorisation

Trois fenêtres figurent le Web, l’UI dessinée par GPU et le natif ; leurs lignes convergent vers une marque rouge de vérification.

Le 12/12/2025, mikayla-maki, ingénieure chez Zed, a fermé une PR proposant des shaders personnalisés pour GPUI. La réponse était courtoise. Après avoir remercié l’auteur, elle expliquait : “we’re shifting focus to core product work at Zed, and without a Zed use case, I can’t validate this code”. Le message se terminait par un sourire.

GPUI est le framework d’interface GPU développé par Zed. Il revient souvent parmi les alternatives à Electron. Moins de quatre mois auparavant, Zed avait annoncé une levée de 32,000,000 de dollars menée par Sequoia, portant son financement total au-delà de 42,000,000 de dollars.

Plus de neuf mois après, le 26/9/2026, le développeur egoist a créé un dépôt nommé MyGo. Après 39 jours, il comptait 1,042 commits, dont 890 portant la signature de Claude.

Claude vient d’Anthropic. L’application de bureau d’Anthropic utilise elle-même Electron.

Ces trois faits, réunis, ont quelque chose d’étrange. Nous avons mesuré 10 frameworks sur deux machines pour voir où en est ce domaine.

01Pourquoi ce comparatif

Des applications de bureau comme Claude et Codex utilisent toujours Electron : l’écosystème Web est mature, une même base de code couvre plusieurs plateformes et les modèles le connaissent bien. L’IA réduit le coût du développement, mais la compatibilité et la maintenance multiplateformes demandent toujours du travail.

Le rendu propre sur GPU offre une autre voie, mais GPUI donne toujours la priorité à Zed. Le rendu multiplateforme et un écosystème de composants exigent un investissement durable. MyGo montre comment l’IA et les composants existants accélèrent les débuts ; sa maturité en production et sa maintenance à long terme restent à démontrer.

Flutter, Compose, Slint, egui et iced font des compromis différents. Nous avons testé 10 frameworks avec les mêmes scénarios, en mesurant la fluidité, le CPU, la mémoire et la fidélité visuelle pour connaître le coût réel de chaque approche.

02Nous avons testé en local

Nous avons testé 10 frameworks avec les mêmes scénarios sur un Apple M4 Max et un ThinkPad T14 Gen6. Le CPU et la mémoire ont été mesurés sur les deux plateformes ; Windows dispose aussi de mesures externes des images avec PresentMon. Sur Mac, les callbacks d’image diffèrent selon les frameworks et ne servent pas à les comparer. Le matériel et les indicateurs mémoire diffèrent également : les comparaisons restent donc propres à chaque plateforme.

La scène d’animation est dense : 500 cartes de 96×64 pixels logiques se chevauchent sur 25 colonnes. Chacune possède un rayon de coin de 12, un dégradé à 135° et une ombre de blur 16 décalée de 4 vers le bas. Leurs positions sont mises à jour à chaque image selon un cercle de rayon 12 et de période 4 secondes. Nous présentons la médiane de cinq essais de 30 secondes.

Nous mesurons surtout le coût CPU de la mise à jour de l’interface, de la préparation du dessin et de la soumission du rendu lorsque de nombreux éléments avec effets bougent continuellement, ainsi que la régularité des images. Le CPU couvre l’arbre des processus de l’application, pas l’utilisation du GPU ni le temps par étape. Il faut le lire avec les intervalles entre images : produire moins d’images peut aussi réduire le CPU. Les 500 cartes sont présentes dans la scène ; le chevauchement et le découpage de la fenêtre empêchent leur dessin intégral à chaque image.

500 cartes arrondies bleu-violet superposées, avec dégradés et ombres
Figure 1Scène de test de charge : 500 cartes avec dégradés et ombres. Electron / macOS, capture de l’application de test figée à la position initiale.

Windows

Tableau 1Mesures Windows, médiane de 5 passages. Images : intervalle d’affichage p95 (ms), 8.3 correspondant au plein 120Hz. CPU : un cœur logique vaut 100%. Mémoire : private commit (MiB).
FrameworkListe : intervalleAnim. : intervalleCPU fluxCPU éditionCPU anim.RAM anim.
WPF (natif)8.668473%13%49%2,425
Electron8.810831%92%138%947
TauriInvalide9254%105%148%913
GPUI8.616.724%4%22%142
MyGo8.48.611%6%33%115
egui8.88.512%20%49%388
iced8.98.520%3%25%215
Slint8.58.527%99%67%61
Flutter8.48022%105%91%4,934
Compose8.816034%106%102%2,422

Tous suivent le défilement de liste. L’écart apparaît avec l’animation : pour 500 cartes avec ombres et dégradés, les frameworks à rendu propre en Rust et Go tiennent globalement les 120Hz. Flutter, Electron, Tauri et Compose atteignent des intervalles de 80 à 160ms. Les 684ms de WPF viennent de 500 effets d’ombre indépendants. Sans eux, il revient à 8.3ms : ce n’est donc pas un problème général.

L’édition de texte est un autre obstacle. Avec 10 caractères insérés par seconde dans un document de 5,000 lignes, Flutter, Compose et Slint saturent un cœur. Sous Windows, Flutter perd aussi trente pour cent des entrées.

Mac

Tableau 2Mesures Mac, médianes de 5 essais. CPU : un cœur logique représente 100% ; mémoire : phys_footprint (MiB). La machine n’était pas au repos. Aucune fréquence d’images comparable entre frameworks n’est publiée.
FrameworkCPU fluxCPU éditionCPU anim.Mémoire listeRAM anim.
SwiftUI87.5%8.9%99.1%4037
Electron16.1%62.0%102.2%536698
Tauri42.1%86.9%78.7%753555
GPUI22.5%2.9%17.0%341335
MyGo8.2%2.8%16.3%368371
egui8.6%7.2%20.4%803839
iced18.2%7.5%15.0%489491
Slint18.4%52.1%26.7%423416
Flutter18.3%101.9%237.4%468994
Compose31.3%105.1%107.5%7101,295

Sur Mac, le CPU d’animation atteignait environ 15%–20% pour GPUI, MyGo, egui et iced, contre 237% pour Flutter et autour de 100% pour Electron et Compose. En édition de texte, Flutter et Compose approchaient toujours un cœur complet. Slint était à 52%, contre 99% sous Windows.

Pour la liste, les quelque 40 MiB de SwiftUI, 340 MiB de GPUI et 800 MiB d’egui décrivent avant tout l’empreinte des processus de l’application. Une UI native peut utiliser des services de rendu système externes : Apple indique qu’AppKit préfère rendre les arbres de calques hors processus. Une partie du dessin et de la composition se fait donc ailleurs. Les moteurs personnalisés utilisent aussi la composition système, mais leurs seuls chiffres de processus ne permettent pas de comparer la répartition du travail. La mémoire unifiée des puces M partage la mémoire physique entre CPU et GPU ; elle n’impute pas tous les coûts au phys_footprint de l’application.

Dans cinq courtes traces GPU par scène de liste et d’animation SwiftUI, aucun événement d’exécution GPU du PID de l’application n’a été observé, tandis que WindowServer était actif. Cela ne signifie ni que SwiftUI n’utilise pas le GPU, ni que toute l’activité du bureau lui revient. La référence mémoire de WindowServer fluctuait d’environ 205 MiB ; l’absence de gros objets partagés dans les instantanés n’exclut pas non plus la réutilisation de ressources système existantes. Ces mesures établissent seulement une empreinte de processus plus faible pour SwiftUI, pas un coût global de rendu inférieur ni une prise en charge intégrale de l’écart par le système.

Ces chiffres ne valent que pour ces deux machines, ces versions et nos programmes de test. La méthode et les données complètes figurent à la section 05.

03Il n’a jamais fallu n’en choisir qu’un

Les éditeurs, outils de développement et applications métier ont des besoins différents en saisie de texte, animation, mémoire, livraison multiplateforme et composants. Chacun a ses usages. Choisir un framework revient à décider quels compromis sont acceptables.

De nombreux frameworks utilisent aussi la rétention, le cache et les mises à jour partielles pour éviter de répéter la mise en page et le dessin. GPUI combine les modes immédiat et retenu. Le modèle d’interface, le travail réutilisable et le temps nécessaire pour dessiner une image sont des questions distinctes.

MyGo, iced, GPUI, Slint et egui suivent tous le rythme des animations, avec une faible utilisation du CPU. Slint utilise le moins de mémoire, egui en consomme plutôt beaucoup et les contrôles d’édition de GPUI sont à fournir soi-même. MyGo sert actuellement surtout aux applications de son auteur et n’a pas encore été validé à grande échelle en production.

Flutter, Electron et Compose ont également présenté des intervalles entre images et une consommation de ressources peu satisfaisants dans ce test de charge d’animation. Le paquet de Tauri ne pèse que 11 MB, mais sa consommation de mémoire à l’exécution est proche de celle d’Electron.

04Le blocage est dans la vérification

Nous pensons maintenant que la vérification compte plus que le rendu.

Écrire du code coûte moins cher, mais vérifier qu’il est correct prend toujours du temps. Dans l’enquête développeurs Stack Overflow 2025, 66% avaient rencontré des solutions d’IA “almost right, but not quite”, et 45.2% déclaraient passer plus de temps à déboguer le code de l’IA. Selon une enquête publiée par Sonar en 01/2026, 96% ne faisaient pas entièrement confiance à la correction fonctionnelle du code généré, et seulement 48% disaient toujours le vérifier avant un commit. Sonar vend des outils d’inspection de code : ses chiffres appellent une certaine prudence, mais rejoignent ceux de la première enquête.

Les publications de Slint et egui ont peu fait parler d’elles. Nous les jugeons plus importantes que les progrès du rendu. Un agent doit pouvoir injecter des entrées et prendre des captures pour modifier, regarder, puis corriger à nouveau. Avant, vérifier une interface demandait à quelqu’un de s’asseoir devant la machine et de cliquer partout. Les machines commencent à pouvoir s’en charger.

Il existe aujourd’hui trois façons de faire. Le Web multiplateforme possède le plus d’acquis. Le rendu propre sur GPU évite d’embarquer un navigateur et sa mise en place est plus accessible qu’avant. Le natif sur chaque plateforme est la méthode la plus ancienne. Autrefois, seules les grandes entreprises pouvaient financer plusieurs équipes. La difficulté actuelle, ce sont les bugs et le périmètre d’assistance triplés décrits par Breunig. Si la vérification coûte moins cher et que la qualité s’améliore, générer directement une application native par plateforme pourrait aussi fonctionner.

Nous explorons aussi notre propre GPU UI. La différence consiste à y apporter une grande partie de la DX du Web : composants proches de JSX, styles proches de CSS, disposition flexbox, état réactif et DevTools semblables à ceux du navigateur, le tout compilé en code natif. Le projet en est encore à ses débuts.

Nous ne savons pas quelle réponse gagnera. Plusieurs pourraient coexister longtemps. Les trois faits du début restent inchangés. La PR est toujours fermée, MyGo grandit et l’application de bureau Claude reste sur Electron. C’est une période très intéressante.

05Rapport expérimental

Les essais ont eu lieu du 4 au 6 novembre 2026. Les mêmes scénarios ont été réalisés pour chaque framework avec les pratiques recommandées, les paramètres par défaut et des versions compilées pour la production. Après correction du flou, nous avons remesuré la page de design de Compose et le scénario au repos qui partage son implémentation.

Tableau 3Environnements de test. Les machines diffèrent par le matériel, les fenêtres et les métriques mémoire. Nous comparons donc au sein de chaque plateforme, pas les valeurs absolues entre plateformes.
ÉlémentMacWindows
MachineApple M4 Max, 16 cœurs, 64 GBThinkPad T14 Gen6, Core Ultra 7 255H, GPU intégré Arc 140T, 32 GB
SystèmemacOS 26.4Windows 11 Pro 10.0.26300
ÉcranStudio Display,60Hz,2x2880×1800,120Hz,200%
Fenêtre1440×900 pixels logiques1280×720 pixels logiques ; page de design 1440×900 sans bordure
Métrique mémoirephys_footprintprivate commit (mémoire privée engagée, pas l’occupation physique)
Métrique imagesCallbacks de l’application ; sens différent selon le framework, exclus des comparaisonsIntervalle d’affichage PresentMon 2.6.0, mesure externe
État de la machineNon au repos ; autres tâches de développement pendant les testsAucune autre action utilisateur
Tableau 4Frameworks et versions testés. Les chemins de rendu viennent des journaux d’exécution ou des valeurs réellement renvoyées par les API. « Non vérifié » signifie qu’aucune preuve à l’exécution n’a été obtenue.
FrameworkVersionRendu MacRendu Windows
SwiftUI / WPFmacOS 26.4 SDK / .NET Framework 4.8.1Composition systèmePipeline D3D9 par défaut de WPF
Electron45.2.2Non vérifiéChromium,ANGLE D3D11
Tauri2.12.5WKWebViewWebView2 156,ANGLE D3D11
GPUIZed c4273271Metal, réglages par défautNon vérifié
MyGo86ec3b30Non vérifiéNon vérifié
eguieframe 0.37.0MetalVulkan
iced0.14.0MetalVulkan
Slint1.18.1FemtoVG,OpenGLFemtoVG,OpenGL ES
Flutter3.47.9Impeller,MetalImpeller,ANGLE D3D11
Compose1.12.2Skiko,MetalSkiko,D3D12
Tableau 5Scénarios de test. Ils sont pilotés par des temporisateurs internes, sans intervention manuelle. Les données sont générées avec une graine fixe.
ScénarioTravail effectué
ReposAfficher la page de design sans la modifier pour mesurer le coût au repos
ListeListe virtualisée de 10,000 lignes, hauteur 64, défilement constant à 2,000 px/s
FluxCharger 200 anciens messages, puis ajouter 40 mots par seconde au dernier, toujours en bas
ÉditionDocument de 5,000 lignes, insertion de 10 caractères par seconde au curseur
Animation500 cartes de 96×64, rayon 12, dégradé et ombre, mouvement circulaire selon une formule commune
Page de design11 spécifications : polices, ombres, traits fins, dégradés, P3, flou d’arrière-plan, coins arrondis, emoji, OpenType, composition mixte chinois-anglais

Chaque scénario a été exécuté 5 fois par framework, 30 secondes par passage, en série et dans un ordre mélangé. Les tableaux donnent les médianes. La médiane des étendues entre les 5 passages était d’environ 3% ; neuf dixièmes restaient sous 24%. Liste et animation ont été remesurées après harmonisation des spécifications : les colonnes ne viennent donc pas de la même période. Un cœur logique vaut 100% de CPU. Les applications multiprocessus incluent tous leurs processus enfants. Pour Tauri sur Mac, nous avons aussi compté les processus WebKit lancés pour lui par le système. Sur Windows, seules les séries attribuables sans ambiguïté à un swapchain et sans perte d’enregistrements sont retenues pour les images.

Nous avons vérifié le travail effectivement livré pour le flux et l’édition : sur Windows, Flutter n’a terminé que 68% de l’édition ; tous les autres dépassaient 99%.

Tableau 6CPU Windows, en %.
FrameworkReposListeFluxÉditionAnimation
WPF2.637.272.713.549.3
Electron6.142.830.692.1137.8
Tauri31.658.253.7104.9147.8
GPUI1.510.624.33.621.5
MyGo0.017.910.66.332.8
egui0.315.912.219.648.9
iced0.321.320.23.024.5
Slint0.362.726.999.166.8
Flutter0.631.221.8104.690.6
Compose0.535.934.4106.4101.8
Tableau 7Mémoire Windows, private commit, en MiB.
FrameworkReposListeFluxÉditionAnimation
WPF1571932502062,425
Electron280397392556947
Tauri260313346536913
GPUI135142160138142
MyGo132135133132115
egui379386396460388
iced212224274321215
Slint79877220261
Flutter6363963746674,934
Compose4215445743,3722,422
Tableau 8Intervalle d’affichage Windows, en ms. À 120Hz, 8.33 correspond à la cadence maximale. Passages désigne ceux disposant de données d’images valides.
FrameworkListe p95Liste p99PassagesAnim. p95Anim. p99Passages
WPF8.68.75684.3719.35
Electron8.88.94108.3115.92
Tauri——091.7100.05
GPUI8.68.8516.725.15
MyGo8.48.758.616.75
egui8.88.958.58.75
iced8.98.958.58.65
Slint8.58.858.58.75
Flutter8.48.6580.588.65
Compose8.88.95160.3211.85
Tableau 9CPU Mac, en %. Machine non au repos.
FrameworkReposListeFluxÉditionAnimation
SwiftUI1.016.987.58.999.1
Electron2.516.716.162.0102.2
Tauri6.332.042.186.978.7
GPUI0.49.722.52.917.0
MyGo0.113.28.22.816.3
egui0.19.08.67.220.4
iced0.124.218.27.515.0
Slint0.113.118.452.126.7
Flutter0.211.018.3101.9237.4
Compose0.423.331.3105.1107.5
Tableau 10Mémoire Mac, phys_footprint, en MiB.
FrameworkReposListeFluxÉditionAnimation
SwiftUI324013629337
Electron205536567707698
Tauri101753601570555
GPUI74341358320335
MyGo75368361356371
egui414803817862839
iced75489541598491
Slint151423386434416
Flutter156468455663994
Compose3507107091,4261,295
Tableau 11Démarrage : du lancement du processus au premier callback d’image (ms), et non au premier écran avec cache froid. Taille : répertoire de distribution (MB), hors WebView système et .NET.
FrameworkDémarrage MacDémarrage WindowsTaille MacTaille Windows
Natif (SwiftUI / WPF)2284493.0<0.1
Electron295818267.0376.4
Tauri56562212.511.2
GPUI25527711.913.4
MyGo74212613.111.5
egui30927717.417.4
iced25759014.414.2
Slint26127218.517.0
Flutter2441,04343.930.0
Compose5501,074123.1113.8

Fidélité au design

Le test de flou consiste à adoucir les transitions entre les bandes colorées dans un panneau précis de la fenêtre. Avec Modifier.blur réglé à 24 dp sur la couche de bandes dans Compose 1.12.2, les captures des fenêtres natives sur Mac et Windows montrent des transitions douces. SwiftUI applique lui aussi le flou à la couche de bandes connue avant de la recouvrir de blanc translucide. Les deux vérifications portent sur cette couche précise. API Compose Desktop

Panneaux à bandes de dix frameworks. Compose, SwiftUI, Electron, Tauri, MyGo et Flutter présentent des transitions douces. Les quatre autres conservent des frontières nettes entre les couleurs.
Figure 2Captures de fenêtres natives sur Mac à 2×, recadrées sur le même panneau et réduites proportionnellement.

Les implémentations testées de GPUI, iced, egui et Slint superposent une couche translucide aux bandes. Les frontières entre les couleurs restent nettes lors du nouvel essai. Blurred dans GPUI et window::Settings::blur dans iced agissent sur le contenu derrière la fenêtre. Nous n’avons trouvé aucune API de dessin intégrée pour le flou d’arrière-plan local dans les versions testées. iced permet de dessiner des effets locaux sur mesure, et egui peut appeler le moteur de rendu via PaintCallback. GPUI · Paramètres de fenêtre d’iced · Callback de dessin d’egui

Slint a été testé avec la version 1.18.1 et FemtoVG. Cette version ne proposait pas la propriété d’élément backdrop-blur. Le projet l’a ensuite ajoutée pour le moteur Skia. Les captures correspondent au rendu FemtoVG de la version 1.18.1. Ticket du projet Slint

La page comporte 11 vérifications. GPUI, egui, iced, Slint et Compose n’ont pas reproduit l’échantillon P3 dans la sortie Mac testée. Les captures Windows n’ont pas de profil couleur : P3 n’est pas évalué et les drapeaux emoji apparaissent sous forme de lettres.

Tableau 12Choix techniques des modules clés, d’après le code source et la documentation officielle des versions fixées.
FrameworkDispositionTexteAccessibilité
GPUITaffyCoreText sur macOSAccessKit
eguiDisposition en mode immédiatepaint + harfrustAccessKit
icedDisposition flex proprecosmic-textAucun pont système trouvé
SlintLowering à la compilation + disposition à l’exécutionParleyAccessKit
FlutterContraintes RenderBoxSkParagraphPont de l’arbre Semantics
ComposeMeasurePolicySkParagraph de SkikoSemantics ; Java Access Bridge requis sous Windows
ElectronBlinkPipeline texte ChromiumArbre d’accessibilité Chromium
TauriWebView systèmeWebView systèmeExposé par WebView
SwiftUIStack / LayoutTextKit,Core TextIntégré au système

La disposition converge ; le texte reste la principale divergence. Quand iced demande PingFang 700 sur macOS, les lettres latines se rabattent sur Menlo Bold.

Limites :

  • Une seule machine par plateforme. Les résultats d’animation viennent d’un GPU intégré Intel et ne s’appliquent pas forcément aux GPU dédiés.
  • Le Mac n’était pas au repos pendant les tests. Les données d’images viennent uniquement des callbacks de l’application et ne servent pas à comparer les frameworks.
  • La sémantique du blur des ombres varie. egui, iced et GPUI en donnent une approximation. Les contrôles d’édition ne sont pas équivalents non plus ; GPUI utilise un éditeur d’exemple modifié.
  • Les tableaux CPU et mémoire couvrent l’application et les processus auxiliaires inclus. Les coûts de WindowServer et du pilote ne sont pas répartis par fenêtre, et les gains de réutilisation des ressources système partagées ne sont pas quantifiés ; aucun classement du coût global de rendu n’en découle.
  • Les mesures des fenêtres de candidats des méthodes de saisie, de l’arbre d’accessibilité sur Mac et de la consommation électrique n’ont pas donné de résultats exploitables.
L

La rédaction de ui.surf

La rédaction de ui.surf · 1 article