Aprofundamento

Engenharia de UI na era da IA

Antes da IA, a Web multiplataforma era uma boa resposta. Agora ficou mais barato escrever código, mas verificá-lo ainda custa o mesmo. Tanto a UI com GPU quanto a geração de apps nativos para cada plataforma ganharam espaço. Testamos 10 frameworks.

OriginalProibida a reprodução sem autorização

Três janelas representam Web, UI desenhada por GPU e nativo; as linhas convergem para uma marca vermelha de verificação.

Em 12/12/2025, a engenheira da Zed mikayla-maki fechou um PR que propunha adicionar shaders personalizados ao GPUI. A resposta foi cordial. Depois de agradecer a contribuição, explicou: “we’re shifting focus to core product work at Zed, and without a Zed use case, I can’t validate this code”. A mensagem terminava com um sorriso.

GPUI é o framework de interface com GPU criado pela própria Zed. Ele aparece com frequência nas conversas sobre alternativas ao Electron. Menos de quatro meses antes, a Zed havia anunciado uma rodada de US$ 32,000,000 liderada pela Sequoia, levando o total captado a mais de US$ 42,000,000.

Mais de nove meses depois, em 26/9/2026, o desenvolvedor egoist criou um repositório chamado MyGo. Após 39 dias, eram 1,042 commits, dos quais 890 tinham a assinatura do Claude.

Claude é da Anthropic. O aplicativo de desktop da própria Anthropic usa Electron.

Juntos, esses três fatos parecem um pouco estranhos. Medimos 10 frameworks em duas máquinas para entender em que ponto esse campo está.

01Contexto da avaliação

Aplicativos de desktop como Claude e Codex ainda usam Electron: a Web tem um ecossistema maduro, uma base de código atende a várias plataformas e os modelos a conhecem bem. A IA reduz o custo de desenvolvimento, mas a compatibilidade entre plataformas e a manutenção continuam exigindo trabalho.

A renderização própria por GPU oferece outro caminho, mas o GPUI ainda prioriza o Zed. Renderização multiplataforma e um ecossistema de componentes exigem investimento contínuo. O MyGo mostra como a IA e os componentes existentes aceleram o início; sua maturidade em produção e manutenção a longo prazo ainda precisam ser comprovadas.

Flutter, Compose, Slint, egui e iced fazem escolhas diferentes. Testamos 10 frameworks com os mesmos cenários, medindo fluidez, CPU, memória e fidelidade visual para entender o custo real de cada abordagem.

02Fizemos testes locais

Testamos 10 frameworks com os mesmos cenários em um Apple M4 Max e um ThinkPad T14 Gen6. Medimos CPU e memória nas duas plataformas; o Windows também conta com medições externas de quadros pelo PresentMon. Os callbacks de quadros no Mac diferem entre frameworks e não são usados para compará-los. O hardware e as métricas de memória também são distintos, por isso só comparamos dentro de cada plataforma.

A animação é uma cena densa: 500 cartões de 96×64 pixels lógicos, sobrepostos em 25 colunas, com raio de canto 12, gradiente de 135° e sombra com blur 16 e deslocamento vertical 4. Todos atualizam a posição a cada quadro, descrevendo círculos de raio 12 e período de 4 segundos. Publicamos a mediana de cinco rodadas de 30 segundos.

O foco é o custo de CPU para atualizar a interface, preparar o desenho e submeter a renderização enquanto muitos elementos com efeitos se movem continuamente, além da regularidade dos quadros. A CPU inclui a árvore de processos do aplicativo; não é utilização de GPU nem tempo por etapa. Deve ser lida junto ao intervalo entre quadros: produzir menos quadros também pode reduzir a CPU. Os 500 cartões pertencem à cena; sobreposição e recorte da janela impedem que todos sejam desenhados integralmente a cada quadro.

500 cartões arredondados azuis e roxos sobrepostos, com gradientes e sombras
Figura 1Cena de teste de carga de animação: 500 cartões com gradientes e sombras. Electron / macOS, captura do aplicativo de teste congelado na posição inicial.

Windows

Tabela 1Medições no Windows, mediana de 5 rodadas. Frames: intervalo de exibição p95 (ms); 8.3 corresponde a 120Hz completos. CPU: um núcleo lógico equivale a 100%. Memória: private commit (MiB).
FrameworkLista: intervaloAnim.: intervaloCPU fluxoCPU ediçãoCPU anim.RAM anim.
WPF (nativo)8.668473%13%49%2,425
Electron8.810831%92%138%947
TauriInválido9254%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

Todos acompanharam a rolagem da lista. A diferença apareceu na animação: com 500 cartões com sombras e gradientes, os frameworks de desenho próprio em Rust e Go mantiveram em geral os 120Hz. Flutter, Electron, Tauri e Compose chegaram a intervalos de 80 a 160ms. Os 684ms do WPF vieram de 500 efeitos de sombra independentes. Ao desligá-los, voltou a 8.3ms, então não é um problema geral.

A edição de texto é outro obstáculo. Inserindo 10 caracteres por segundo em um documento de 5,000 linhas, Flutter, Compose e Slint saturaram um núcleo. No Windows, o Flutter também perdeu trinta por cento das entradas.

Mac

Tabela 2Medições do Mac, medianas de 5 rodadas. CPU: um núcleo lógico equivale a 100%; memória: phys_footprint (MiB). A máquina não estava ociosa. Não são apresentadas taxas de quadros comparáveis entre frameworks.
FrameworkCPU fluxoCPU ediçãoCPU anim.Memória da listaRAM 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

No Mac, o CPU de animação ficou em cerca de 15%–20% para GPUI, MyGo, egui e iced, contra 237% para Flutter e aproximadamente 100% para Electron e Compose. Na edição de texto, Flutter e Compose ainda chegaram perto de um núcleo inteiro. Slint usou 52%, abaixo de seus 99% no Windows.

Na lista, os cerca de 40 MiB do SwiftUI, 340 MiB do GPUI e 800 MiB do egui descrevem primeiro o footprint dos processos do aplicativo. A UI nativa pode usar serviços de renderização externos do sistema: a Apple documenta que o AppKit prefere renderizar árvores de camadas fora do processo. Parte do desenho e da composição ocorre, portanto, fora do aplicativo. Renderizadores próprios também usam a composição do sistema, mas os números do processo não bastam para comparar a divisão do trabalho. A memória unificada dos chips M compartilha memória física entre CPU e GPU; isso não atribui todos os custos ao phys_footprint do aplicativo.

Em cinco traces GPU curtos por cenário de lista e animação do SwiftUI, não foram observados eventos de execução GPU do PID do aplicativo, enquanto o WindowServer estava ativo. Isso não significa que o SwiftUI não use GPU nem atribui a ele toda a atividade do desktop. A memória de referência do WindowServer oscilou cerca de 205 MiB; a ausência de grandes objetos compartilhados nos snapshots também não exclui o reaproveitamento de recursos existentes do sistema. Os dados mostram apenas menor footprint do processo SwiftUI, não menor custo total de renderização nem que o sistema pague toda a diferença.

Esses números descrevem apenas essas duas máquinas, essas versões e nossos programas de teste. O método e os dados completos estão na seção 05.

03Nunca foi uma questão de escolher só um

Editores, ferramentas de desenvolvimento e aplicativos de negócio têm requisitos diferentes de entrada de texto, animação, memória, distribuição multiplataforma e ecossistemas de componentes. Cada um tem seus casos de uso. Escolher um framework significa decidir quais concessões são aceitáveis.

Muitos frameworks também usam retenção, cache e atualizações parciais para evitar repetir o cálculo de layout e o desenho. O GPUI combina os modos imediato e retido. O modelo de interface, o trabalho que pode reutilizar e o tempo para desenhar um quadro são questões distintas.

MyGo, iced, GPUI, Slint e egui acompanham bem as animações, com baixo uso de CPU. O Slint é o que usa menos memória, o egui tem uso de memória relativamente alto e os controles de edição do GPUI precisam ser acrescentados por quem o usa. O MyGo é usado atualmente principalmente nos aplicativos do próprio autor e ainda não foi validado em larga escala em produção.

Flutter, Electron e Compose também apresentaram intervalos entre quadros e uso de recursos pouco satisfatórios neste teste de carga de animação. O pacote do Tauri tem só 11 MB, mas seu uso de memória em execução é parecido com o do Electron.

04O gargalo está na verificação

Agora achamos que a verificação é mais importante que a renderização.

Escrever código ficou mais barato, mas confirmar que está correto ainda leva tempo. Na pesquisa de desenvolvedores do Stack Overflow de 2025, 66% tinham recebido soluções de IA “almost right, but not quite”, e 45.2% disseram gastar mais tempo depurando código de IA. Em uma pesquisa publicada pela Sonar em 01/2026, 96% não confiavam totalmente na correção funcional do código gerado por IA, e só 48% afirmavam sempre verificá-lo antes do commit. A Sonar vende ferramentas de inspeção de código, então cabe alguma cautela com os números, mas eles concordam com a outra pesquisa.

Os lançamentos de Slint e egui fizeram pouco barulho. Para nós, são mais importantes que os avanços de renderização. Agentes precisam injetar entradas e tirar capturas para alterar algo, olhar e alterar de novo. Antes, verificar uma interface exigia alguém sentado diante da máquina, clicando em cada item. Agora essa tarefa começa a poder ser passada à máquina.

Há três formas de fazer isso hoje. A Web multiplataforma tem mais recursos acumulados. O desenho próprio com GPU dispensa levar um navegador, e a barreira para construí-lo é menor do que antes. Fazer um app nativo para cada plataforma é o método mais antigo. Antes, só grandes empresas podiam manter várias equipes. A dificuldade agora são os bugs e o escopo de suporte triplicados de que Breunig fala. Se o custo de verificar cair e a qualidade subir, gerar diretamente um app nativo por plataforma também pode funcionar.

Também estamos explorando nossa própria GPU UI. A diferença é trazer boa parte da DX da Web: componentes parecidos com JSX, estilos parecidos com CSS, layout flexbox, estado reativo e DevTools como os do navegador, tudo compilado em código nativo. Ainda estamos no início.

Não sabemos qual resposta vai vencer. Várias podem coexistir por muito tempo. Os três fatos do começo continuam iguais: o PR segue fechado, MyGo continua crescendo e o desktop do Claude ainda é Electron. É um período muito interessante.

05Relatório experimental

Os testes foram feitos de 4 a 6 de novembro de 2026. Cada framework implementou os mesmos cenários com as práticas recomendadas, a configuração padrão e builds de produção. Depois de corrigir o desfoque, medimos novamente a página de design do Compose e o cenário em repouso que compartilha sua implementação.

Tabela 3Ambientes de teste. As máquinas diferem em hardware, janelas e métricas de memória. Por isso, comparamos apenas dentro da mesma plataforma, não os valores absolutos entre plataformas.
ItemMacWindows
MáquinaApple M4 Max, 16 núcleos, 64 GBThinkPad T14 Gen6, Core Ultra 7 255H, GPU integrada Arc 140T, 32 GB
SistemamacOS 26.4Windows 11 Pro 10.0.26300
TelaStudio Display,60Hz,2x2880×1800,120Hz,200%
Janela1440×900 pixels lógicos1280×720 pixels lógicos; página de design 1440×900 sem bordas
Métrica de memóriaphys_footprintprivate commit (memória privada comprometida, não o uso físico)
Métrica de framesCallbacks da aplicação; significados variam entre frameworks, sem comparaçãoIntervalo de exibição do PresentMon 2.6.0, medição externa
Estado da máquinaNão ociosa; outras tarefas de desenvolvimento durante os testesSem outras ações do usuário
Tabela 4Frameworks e versões testados. Os caminhos de renderização vêm de logs de execução ou retornos reais das APIs. “Não verificado” indica que não obtivemos evidência em execução neste teste.
FrameworkVersãoRenderização MacRenderização Windows
SwiftUI / WPFmacOS 26.4 SDK / .NET Framework 4.8.1Composição do sistemaPipeline D3D9 padrão do WPF
Electron45.2.2Não verificadoChromium,ANGLE D3D11
Tauri2.12.5WKWebViewWebView2 156,ANGLE D3D11
GPUIZed c4273271Metal, configuração padrãoNão verificado
MyGo86ec3b30Não verificadoNão verificado
eguieframe 0.37.0MetalVulkan
iced0.14.0MetalVulkan
Slint1.18.1FemtoVG,OpenGLFemtoVG,OpenGL ES
Flutter3.47.9Impeller,MetalImpeller,ANGLE D3D11
Compose1.12.2Skiko,MetalSkiko,D3D12
Tabela 5Cenários de teste. Temporizadores internos os controlam sem operação manual. Os dados são gerados com uma semente fixa.
CenárioCarga de trabalho
ParadoMostrar a página de design e deixá-la parada para medir o custo ocioso
ListaLista virtualizada de 10,000 linhas, altura 64, rolagem constante a 2,000 px/s
FluxoCarregar 200 mensagens anteriores e adicionar 40 palavras por segundo à última, sempre no fim
EdiçãoDocumento de 5,000 linhas, inserindo 10 caracteres por segundo no cursor
Movimento500 cartões de 96×64, raio 12, gradiente e sombra, em movimento circular pela mesma fórmula
Página de design11 especificações: fontes, sombras, linhas finas, gradientes, P3, desfoque de fundo, cantos arredondados, emoji, OpenType e composição mista em chinês e inglês

Cada cenário rodou 5 vezes por framework, durante 30 segundos por rodada, em série e com a ordem embaralhada. As tabelas mostram medianas. A mediana da amplitude entre as 5 rodadas foi de cerca de 3%; noventa por cento ficaram dentro de 24%. Lista e animação foram medidas de novo após a padronização das especificações, então as colunas não foram coletadas no mesmo período. Um núcleo lógico equivale a 100% de CPU. Aplicativos multiprocesso incluem todos os processos filhos. No Tauri para Mac, também contamos os processos WebKit que o sistema iniciou para ele. Os dados de frames no Windows usam apenas rodadas atribuíveis de forma única a um swapchain e sem perda de registros.

Conferimos o volume efetivamente entregue no fluxo e na edição: no Windows, o Flutter concluiu só 68% da edição; todos os outros passaram de 99%.

Tabela 6CPU do Windows, em %.
FrameworkParadoListaFluxoEdiçãoMovimento
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
Tabela 7Memória do Windows, private commit, em MiB.
FrameworkParadoListaFluxoEdiçãoMovimento
WPF1571932502062,425
Electron280397392556947
Tauri260313346536913
GPUI135142160138142
MyGo132135133132115
egui379386396460388
iced212224274321215
Slint79877220261
Flutter6363963746674,934
Compose4215445743,3722,422
Tabela 8Intervalo de exibição do Windows, em ms. A 120Hz, 8.33 corresponde à taxa máxima de frames. Rodadas é o número de rodadas com dados válidos de frames.
FrameworkLista p95Lista p99RodadasAnim. p95Anim. p99Rodadas
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
Tabela 9CPU do Mac, em %. Máquina não ociosa.
FrameworkParadoListaFluxoEdiçãoMovimento
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
Tabela 10Memória do Mac, phys_footprint, em MiB.
FrameworkParadoListaFluxoEdiçãoMovimento
SwiftUI324013629337
Electron205536567707698
Tauri101753601570555
GPUI74341358320335
MyGo75368361356371
egui414803817862839
iced75489541598491
Slint151423386434416
Flutter156468455663994
Compose3507107091,4261,295
Tabela 11Inicialização: do início do processo ao primeiro callback de frame (ms), não à primeira tela com cache frio. Tamanho: diretório de distribuição (MB), sem WebView do sistema e .NET.
FrameworkInício MacInício WindowsTamanho MacTamanho Windows
Nativo (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

Fidelidade ao design

O teste de desfoque pede transições suaves entre as faixas coloridas de um painel dentro da janela. Com Modifier.blur de 24 dp na camada das faixas no Compose 1.12.2, as capturas de janelas nativas no Mac e no Windows mostraram transições suaves. O SwiftUI também desfoca primeiro a camada conhecida das faixas e depois aplica uma sobreposição branca translúcida. A verificação dos dois métodos se limita a essa camada. API do Compose Desktop

Painéis com faixas de dez frameworks. Compose, SwiftUI, Electron, Tauri, MyGo e Flutter mostram transições suaves. Os outros quatro mantêm bordas bem definidas entre as faixas.
Figura 2Capturas de janelas nativas no Mac em 2×, recortadas para mostrar o mesmo painel e reduzidas proporcionalmente.

As implementações testadas de GPUI, iced, egui e Slint aplicaram uma camada translúcida sobre as faixas. As bordas das faixas continuaram bem definidas no novo teste. O Blurred do GPUI e o window::Settings::blur do iced afetam o conteúdo atrás da janela. Não encontramos uma API de desenho nativa para desfoque de fundo localizado nas versões testadas. O iced permite desenhar efeitos locais com renderização personalizada, e o egui pode acessar o renderizador por meio de PaintCallback. GPUI · Configurações de janela do iced · Callback de desenho do egui

O Slint foi testado na versão 1.18.1 com FemtoVG. Essa versão não oferecia a propriedade de elemento backdrop-blur. O projeto a adicionou depois ao renderizador Skia. As capturas mostram o caminho FemtoVG da versão 1.18.1. Issue do Slint

A página tem 11 verificações. GPUI, egui, iced, Slint e Compose não reproduziram a amostra P3 na saída Mac testada. As capturas Windows não têm perfil de cor, então P3 não é avaliado; bandeiras emoji aparecem como letras.

Tabela 12Escolhas técnicas dos módulos principais, com base no código-fonte e na documentação oficial das versões fixadas.
FrameworkLayoutTextoAcessibilidade
GPUITaffyCoreText no macOSAccessKit
eguiLayout em modo imediatoepaint + harfrustAccessKit
icedLayout flex própriocosmic-textPonte com o sistema não encontrada
SlintLowering na compilação + layout em execuçãoParleyAccessKit
FlutterRestrições RenderBoxSkParagraphPonte da árvore Semantics
ComposeMeasurePolicySkParagraph do SkikoSemantics; Windows depende de Java Access Bridge
ElectronBlinkPipeline de texto do ChromiumÁrvore de acessibilidade do Chromium
TauriWebView do sistemaWebView do sistemaExposto via WebView
SwiftUIStack / LayoutTextKit,Core TextIntegrado ao sistema

O layout converge; a maior diferença está no texto. Ao solicitar PingFang 700 no macOS, o iced usou Menlo Bold como fallback para as letras latinas.

Limitações:

  • Só uma máquina por plataforma. Os resultados de animação vieram de uma GPU integrada Intel e podem não valer para GPUs dedicadas.
  • O Mac não estava ocioso nos testes. Os dados de frames vêm apenas de callbacks do aplicativo e não são comparados entre frameworks.
  • A semântica de blur das sombras varia. egui, iced e GPUI usam aproximações. Os controles de edição também não são equivalentes; o GPUI usa um editor de exemplo modificado.
  • As tabelas de CPU e memória cobrem o aplicativo e os processos auxiliares incluídos. Os custos do WindowServer e do driver não foram distribuídos por janela, e os ganhos de reutilização de recursos compartilhados do sistema não foram quantificados; não é possível classificar o custo total de renderização do sistema.
  • Não obtivemos resultados válidos para as janelas de candidatos do método de entrada, a árvore de acessibilidade do Mac nem o consumo de energia.
E

Equipe editorial da ui.surf

Equipe editorial da ui.surf · 1 artigo