Nativo até o fim, até você precisar de texto
(justsitandgrin.im)- No macOS, ao criar uma UI de chat em Markdown usando apenas SwiftUI, é possível obter um desempenho básico razoável, mas fica difícil dar suporte à seleção do documento inteiro
- Ao migrar para
NSTextViewe TextKit 2, perde-se o trabalho de testes e desempenho feito em SwiftUI, e surgem picos de CPU com entrada em streaming - Reimplementar com
NSCollectionViewcausa cintilação nas células, e mesmo o TextKit 2 puro, embora tenha desempenho aceitável, não se integra bem com streaming - O WebKit costuma encaixar melhor em renderização de Markdown, desempenho, tipografia e nível de controle, e no Electron o trabalho com texto já funciona por padrão
- Em chats longos e texto rico, o SwiftUI e os SDKs nativos da Apple viram uma limitação, enquanto abordagens baseadas na web levam vantagem no modelo de texto e renderização
Limites de uma UI nativa de chat em Markdown no macOS
- Ao criar um chat simples com suporte a Markdown usando apenas SwiftUI, até dá para alcançar um desempenho básico razoável, mas não é possível selecionar o documento Markdown inteiro quando ele é composto por primitivas do SwiftUI
- Ao migrar para
NSTextView, ganha-se suporte a TextKit 2, mas perde-se a maior parte do trabalho de testes e desempenho feito em SwiftUI, além de a integração com SwiftUI deixar de funcionar bem - Ao inserir respostas do modelo em modo de streaming em
NSTextView, ocorrem picos de CPU - Mesmo reimplementando com
NSCollectionView, as células continuam piscando, e isso permanece como um comportamento difícil de evitar por projeto - Um protótipo em TextKit 2 puro tem desempenho aceitável, mas o streaming continua ruim e ele não combina bem com componentes modernos
- Mesmo removendo completamente o SwiftUI e usando só AppKit, ainda é preciso lidar manualmente com fragmentos de texto que se expandem, e a seleção de texto só se torna possível quando muita coisa já está quebrada
- Para chegar a um nível parecido com o comportamento básico do macOS, é preciso reajustar recursos que o usuário espera naturalmente, como menu de contexto, busca no dicionário, seleção, acessibilidade e interação com texto
Onde WebKit e Electron se encaixam melhor
- Ao renderizar Markdown com WebKit, há alguns pontos de atenção, mas no geral ele funciona bem, oferece bom desempenho e tipografia, além de um nível de controle suficiente
- Ao criar um projeto simples em Electron, edição de texto, renderização de Markdown e boa tipografia já funcionam por padrão, e também se obtém um desempenho que foi mais difícil de alcançar numa implementação pura em TextKit 2
- O Electron também oferece integração com o macOS, permite renderizar diffs de Git sofisticados com poucas linhas de código, e há casos como diffs.com
- Mesmo analisando SwiftUI, AppKit, TextKit e WebKit, continua difícil atender de forma adequada a uma exigência simples como “um chat com suporte a Markdown e seleção da mensagem inteira”
- Fica mais claro por que novos apps em que chat, texto rico de formato longo e tipografia flexível são importantes estão indo para a web
- O SwiftUI é adequado para telas simples sem muita rolagem, e Swift continua útil em partes em que desempenho é importante
- Electron ou React Native conseguem obter bastante desempenho por meio da interoperabilidade nativa, ao mesmo tempo em que mantêm um modelo de texto e renderização melhor
- Na renderização de texto rico para chats longos, o SwiftUI e os SDKs nativos da Apple deixam de ser uma vantagem e passam a ser uma limitação
- Discussões relacionadas: Hacker News, Lobsters
2 comentários
Comentários do Hacker News
Recentemente lancei um editor de texto para iOS usando TextKit 2, e o desempenho ficou alto até com arquivos de 5.000 linhas
Testei com Moby Dick do Project Gutenberg, foi feito entre agosto de 2025 e abril de 2026, e o desenvolvimento continua
A cada tecla digitada, a reestilização acontece em menos de 8 ms, e mesmo 20 entradas rápidas, sem debouncing nem renderização adiada, são processadas em 150 ms incluindo a reestilização completa após cada entrada
Tags e busca booleana terminam em menos de 20 ms, e renderizar só a área visível é 25 vezes mais rápido do que estilizar o documento inteiro, com suporte também a atualização de tela em 120 Hz
O tamanho do app era 722 KB na versão 1.0, e a 1.1, com mais recursos, parece ficar em cerca de 950 KB
Se isso é possível no iOS, no macOS deveria ser umas 10 vezes mais fácil
https://www.gingerbeardman.com/apps/papertrail/
Não quer dizer que seja “impossível”, e sim que dá para entender por que as pessoas escolhem tecnologias web em vez de nativo para esse tipo de coisa. A ideia é construir o produto, não ficar brigando com os limites do sistema
Um visualizador de texto deveria lidar com arquivos pelo menos uma ordem de grandeza maiores. Arquivos JSON com centenas de milhares de linhas são comuns, e CSVs e logs são ainda maiores
Normalmente o motivo para usar APIs nativas em vez de webviews era desempenho, mas agora isso não parece mais necessariamente verdade
Os motores de renderização de navegador amadureceram bastante, ganharam muita aceleração por GPU e foram testados sob estresse por mais de dez anos com web apps inchados
Já o SwiftUI não parece exatamente rápido. A Apple até simplificou a interface dos Ajustes do Sistema refeitos do zero, focando em linhas de checkbox, e ainda assim às vezes trocar de seção engasga mais do que abrir uma página web na us-east-1
Já fiz apps nativos com Qt C++ e QML e mostrei que eles são muito mais rápidos e usam muito menos RAM do que web apps equivalentes
Então, de modo geral, apps web são mais lentos e consomem mais recursos do que apps nativos bem projetados
[1] https://notes.alinpanaitiu.com/SwiftUI%20is%20convenient,%20...
[2] https://x.com/daniel_nguyenx/status/1734495508746702936
[3] https://rubymamistvalove.com/block-editor#8-performance
Eu era desenvolvedor web, mas nos últimos 6 a 12 meses comecei a fazer apps nativos multiplataforma, e a diferença de desempenho é bem grande até em tarefas simples
É estranho jogar fora milhares de anos-pessoa de otimização e milhões de anos-pessoa de validação em produção para reinventar um motor de renderização de texto pior
No macOS, o WebKit é um framework nativo do sistema operacional. Usar WebKit para renderizar Markdown parece completamente apropriado
Claro que renderizar tudo com WebKit faz tão pouco sentido quanto renderizar tudo com PDFKit. Mas para uma view de Markdown, WebKit é uma escolha lógica, e isso não significa que seja preciso virar um app web em Chromium
E o OS X por muito tempo renderizou a UI com DisplayPDF/Quartz
WebKit existe em outras plataformas, então isso seria trapaça? Se for assim, então também poderia usar Java
Se renderizar texto com um renderizador HTML/CSS/JS é “completamente apropriado”, então o que não seria? Por que não renderizar tudo com ele?
Não entendo a lógica que sai de “renderização de texto é apropriada” para “renderizar tudo é absurdo”
Concordo que no macOS o WebKit é um framework nativo do sistema e, nesse sentido, é “nativo”
Mas isso também reforça o ponto maior de que, para lidar direito com rich text, Markdown, seleção, tipografia e conteúdo formatado longo, tecnologias web rapidamente se tornam a única opção prática
Não é que usar WebKit para uma view de Markdown esteja errado; provavelmente é a escolha mais sensata. O problema é que a solução “nativa” aqui acaba sendo, na prática, uma solução de renderização web
Cada
WKWebViewtraz um motor WebKit com seu próprio custo de desempenho e memória, então não dá para espalhar isso por toda parte e tratar como um componente nativo grátis do macOSÉ frustrante que SwiftUI / AppKit / TextKit não ofereçam, para esse tipo de UI, um caminho limpo, moderno e combinável melhor do que “só usa WebKit”
Parece absurdo que algo no nível de “permitir selecionar a mensagem inteira num chat com Markdown” ainda não funcione
No SwiftUI dá para aproveitar renderizadores de Markdown maduros. É só ver https://github.com/gonzalezreal/swift-markdown-ui e seu substituto de próxima geração https://github.com/gonzalezreal/textual
Eu mesmo usei e não tive problema. Até eu, um idiota que não gosta de Swift nem de SwiftUI e prefere Objective-C, consegui fazer sem ajuda de LLM
O scroll de Markdown estático concluído não passou na nova sonda de foco: p95 de 18,86 ms, acima do orçamento de 16,7 ms, com pico de 232,49 ms
O caminho de atualização longa em tempo real de Markdown/código também falhou: p95 de 59,33 ms contra 16,7 ms, com pico de 75,94 ms. É um caso de estresse separado, mas relacionado, de lidar com grandes superfícies de rich text durante atualizações
A expansão de histórico longo tecnicamente passa, mas está longe de parecer suave em frames: 120 turnos p95 21,35 ms, 500 turnos 23,11 ms, 1000 turnos 36,77 ms
Não é ruim, mas é um pouco mais lento do que a minha solução, e a diferença de desempenho parece vir mais do SwiftUI do que da implementação do Textual
Já usei swift-markdown-ui em um app, mas o desempenho não chegava nem perto do wkwebview. Ao fazer streaming de documentos grandes com elementos complicados como tabelas grandes, blocos de código e citações aninhadas, eu chegava a ver a beachball, coisa que não acontecia com wkwebview
Aí eu percebi que navegadores e as tecnologias em torno deles introduziram um novo paradigma de UI que os frameworks nativos de UI não acompanharam
Mesmo preferindo apps nativos a apps baseados na web, foi essa a sensação que tive
Mostra o código ou então pode ir embora. Já existem muitos apps nativos para Mac/iOS que lidam muito bem com renderização de Markdown e texto em streaming
Só queria entender que desculpa exatamente está sendo usada aqui
A maioria acabou se estabelecendo em oferecer seleção apenas dentro de cada bloco contínuo e colocar um botão de copiar para a mensagem inteira
O curioso é que a própria Apple já fez isso no passado
O macOS / AppKit antigo usava WebKit para renderizar rich text dentro de NSTextField nativo. Texto é um problema difícil
Além disso, a WebView nativa é muito rápida e leve, então não é estranho usá-la como motor de layout de texto. Dá até para usar uma WebView separada por linha de uma tabela e ainda assim ter ótimo desempenho
O iMessage para Mac também usava WebView, e o Adium também. Se você vai renderizar texto rico / com marcação, HTML é uma ferramenta totalmente adequada
O Mac nunca usou WebKit para renderização de NSTextField. Quando o iOS foi criado, ele usava WebKit como renderizador de texto de forma bem ampla, incluindo controles do UIKit, e isso era chamado de “sweet solution”
Mas isso acabou se mostrando pesado e incômodo demais, então entrou a abordagem de renderização de texto no estilo Core Text/AppKit
A pessoa descobre que a renderização nativa complexa de texto é difícil, tenta renderizar texto de forma low-level e depois reclama que precisa reimplementar as interações nativas
Então testa WebKit, que funciona muito bem, mas larga isso para voltar a uma situação em que precisa reimplementar as interações nativas
Pessoalmente, eu teria parado no ponto em que WebKit funciona bem
Lembro de quando eu era engenheiro júnior em 2015 e recebi a tarefa de renderizar links clicáveis dentro de um parágrafo num app iOS
Era a época em que Swift tinha acabado de sair, então a stack era totalmente ObjC/UIKit, e foi um verdadeiro pesadelo. No fim consegui fazer funcionar
Como quase não mexi com iOS desde 2016, imaginei que no novo SwiftUI isso obviamente já viria pronto, então é meio insano descobrir que não
https://developer.apple.com/documentation/swiftui/link
Nesse ponto nem sei como isso poderia ficar mais fácil
É natural que “assim que você sai de telas simples, o nativo ainda seja tão imaturo”
Não dá para esperar que algo amadureça se as pessoas não investirem esforço suficiente nisso
Como muito mais esforço vai para tecnologias web, as pessoas ficam presas nisso. Olham para o nativo, dizem que “não evoluiu o bastante” e voltam a fazer mais desenvolvimento web, repetindo o ciclo
No navegador, como “simplesmente funciona”, quase ninguém quer se esforçar para melhorar o nativo
Um dos motivos de a web ser muito mais madura é que os grandes fabricantes comerciais de sistemas operacionais não quiseram acompanhar os tempos. Os toolkits de UI do Windows são realmente uma bagunça
Tive quase exatamente a mesma experiência no meu app de chat com IA. Nada funciona direito
Renderização de Markdown é lenta e engasga, streaming também é lento e engasga, e tudo trava a UI
Testei pelo menos 5 componentes populares de edição de texto para UIKit e SwiftUI no GitHub, e todos estavam quebrados de algum jeito, ou tinham bugs, ou eram lentos. É ridículo
Esse é um problema difícil. Escrevi bastante sobre como resolvi isso ao construir do zero um editor em blocos com Qt C++ e QML
Tive problemas parecidos com seleção entre blocos descontínuos, mostrar o Markdown-fonte sob o cursor e diferentes tamanhos de delegate
Com base no que aprendi ali, estou construindo um cliente LLM nativo com parser de Markdown em streaming
[1] https://rubymamistvalove.com/block-editor
[2] https://www.get-vox.com
Opiniões no Lobste.rs
Electron é basicamente um wrapper em torno de WebView, mas como traz junto todo o engine do Chromium, o preço da conveniência é um app grande demais
Em 2001~2002, implementamos o icônico layout de texto em balões do iChat com
NSTextViewe todo tipo de gambiarra, e mesmo com a ajuda de Hideki Itamura, que era o arquiteto de texto do AppKit, ainda foi bem sofrido. Hoje, com HTML+CSS, isso ficou bem mais simplesParticipei de um app que usava Tauri, e quando mudamos para Electron com Chromium, ele passou a funcionar muito melhor. Também foi importante o fato de o alvo cobrir uma faixa bem ampla, do win7 ao win11
A família Tauri parece boa por usar o webview do sistema, mas no Windows isso acaba sendo Chrome ou Edge, no macOS Safari, e nos outros ambientes é meio que na sorte. No fim, previsibilidade e maturidade venceram, e por algum motivo desconhecido o desempenho também era melhor
No fim, quero software melhor, não agradar gráfico do
htopO ponto central do post não é “todo mundo deveria escolher Electron”, mas que agora dá para entender por que até empresas com recursos e dinheiro ainda escolhem Electron ou tecnologias web. Pelo menos para mim, isso oferece uma boa experiência de uso com compromissos razoáveis nos pontos certos
Há muita gente defendendo o TextKit 2 da Apple ou outros frameworks nativos de texto, mas quase não existem editores de texto populares e de alto desempenho feitos só com os SDKs da Apple. O Xcode faz isso relativamente bem e talvez seja o único caso real de produção. Zed, Sublime Text, Visual Studio Code e as IDEs da JetBrains usam soluções próprias de renderização de texto por um motivo
Então, mesmo que façam tudo da pior maneira possível, no próprio ambiente delas pode parecer aceitável
Enquanto isso, todo o resto, que usa dispositivos muito mais modestos, continua tendo de aguentar software inchado e lento
Só que parece que o autor não foi explorar esse lado aqui
Vendo de fora, Flutter parece uma resposta à ideia de “e se pegássemos o Chromium e deixássemos só o renderizador Skia para usar em apps GUI?”. Deveria ser uma ferramenta multiplataforma mais leve que Electron, mas com capacidades parecidas
DIVcomcontentEditable, e que utiliza uma subclasse deWKWebViewA ironia é que o engine nativo de texto da Apple usa um modelo de dados muito melhor que a árvore DOM do HTML: uma string com atributos de estilo codificados por intervalos de execução
Editar texto no DOM é quase um pesadelo, porque a seleção frequentemente atravessa vários elementos em várias camadas, então é preciso dividir e mesclar tudo de forma muito complexa. Quando mexi pela primeira vez em um build do Safari com suporte a
contenteditable, enviei uma quantidade enorme de relatórios de bug, e até hoje muitos editores web de rich text quebram ao recortar ou colar itens de listaNo fim, parece que aconteceu algo parecido com CISC vs RISC nos anos 90~00. Uma estrutura “inferior” acabou recebendo mais recursos e produziu uma implementação melhor