2 pontos por GN⁺ 12 시간 전 | 2 comentários | Compartilhar no WhatsApp
  • 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 NSTextView e TextKit 2, perde-se o trabalho de testes e desempenho feito em SwiftUI, e surgem picos de CPU com entrada em streaming
  • Reimplementar com NSCollectionView causa 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/

    • Se o recurso central de um produto pago é o editor, dá para entender. Mas se a renderização de Markdown nem é a função principal do app, e em 2026 é mais um recurso de conveniência que o usuário espera, é estranho ter que fazer uma implementação customizada de baixo nível para isso com a mentalidade de gastar 8 meses e continuar desenvolvendo
      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
    • Tendo feito uma ficção interativa com NSString e atributos em 2012, um roguelike com uma API de glifos de baixo nível que foi descontinuada, dois apps de chat com suporte a Markdown em SwiftUI e um jogo idle misturando truques de iOS, eu resumiria essa reação como, no fim das contas, questão de experiência
    • 5.000 linhas é realmente muito pouco, então essa explicação parece confusa. O Moby Dick citado no teste parece ter mais de 22.000 linhas, e até o Bloco de Notas padrão do Windows não engasga com um arquivo desse tamanho
      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
    • A implementação de SwiftUI no Mac provavelmente não é muito boa. Para esse tipo de app, SwiftUI-on-Catalyst pode até ser melhor, mas provavelmente traria outros problemas
    • Duvido bastante da afirmação de que, se funciona no iOS, no macOS seria 10 vezes mais fácil. Apostaria mais no oposto, e queria ouvir isso de alguém que realmente saiba
  • 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

    • O problema aqui não são os apps nativos em geral, e sim o SwiftUI
      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
    • Ainda assim existe uma diferença grande entre um app nativo e o app de navegador mais leve, e isso fica ainda mais evidente em dispositivos de baixa potência
      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
    • Navegadores são péssimos em hardware antigo. Chromebooks velhos são comuns e têm especificações razoáveis para usos leves ou dedicados, mas o navegador roda muito mal
    • Em web apps simples tudo bem, mas em aplicações complexas há uma lentidão perceptível. Nem precisa chegar a um monstro como o Jira; até apps bem otimizados como o VS Code têm um teto de desempenho inferior ao de apps nativos
    • WebView, no fim, também é “nativo”
      É 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

    • Se um motor HTML renderiza rich text, que talvez seja a coisa mais difícil de renderizar numa UI, melhor do que as bibliotecas nativas de UI, então por que não usá-lo também para coisas mais simples como botões e campos de texto?
      E o OS X por muito tempo renderizou a UI com DisplayPDF/Quartz
    • Acho que isso precisa explicar por que renderizar Markdown com WebKit é apropriado
    • O autor original parece tratar “nativo” como usar apenas primitivas Swift/ObjC
      WebKit existe em outras plataformas, então isso seria trapaça? Se for assim, então também poderia usar Java
    • Não entendo por que eu deveria esperar que WebKit seja usado para renderizar rich text
      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”
    • Na prática, a solução atual em andamento é renderizar o Markdown final e o streaming com WebKit
      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 WKWebView traz 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

    • Testei o Textual mais cedo hoje e os resultados não foram muito bons
      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
    • Ele consegue lidar com streaming de texto novo sem cintilação?
    • Se for para renderizar um documento Markdown só uma vez, ou se o documento for simples e curto, provavelmente sim
      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 primeira biblioteca parece ser a usada pelo app iOS do Claude, e aparentemente permite seleção de texto e streaming com desempenho razoável
    • Como usuário, dá para perceber que apps antigos não baseados em HTML não seguem as “regras”. Tem texto que deveria ser selecionável e não é, ou não dá para copiar com control/option C
      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 pessoa diz “quero selecionar o documento Markdown inteiro feito com primitivas de SwiftUI”, mas quem quer isso? Como decisão de produto, isso na prática significa fazer um editor de documentos, uma área difícil há décadas e que parece fora do escopo de uma UI de chat com LLM
      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
    • Se isso é possível sem webview, então compartilhe o código
  • 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

    • Aqui está havendo confusão entre iOS e Mac OS
      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 linha de raciocínio do texto original é um pouco estranha
      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

    • Existe literalmente um Link
      https://developer.apple.com/documentation/swiftui/link
      Nesse ponto nem sei como isso poderia ficar mais fácil
    • O Qt já tornava isso bem fácil 10 anos atrás
    • Não existia o NSLinkAttributeName?
    • Eu achava que texto com atributos já lidava bem com isso há muito tempo. Não era assim?
    • O próprio pedido de colocar links clicáveis dentro de um parágrafo já era uma má ideia
  • É 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

    • Ainda assim, toolkits nativos de UI não são produtos comerciais? Não é papel das pessoas se convencerem sozinhas; é o outro lado que tem de vender isso para elas
      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
    • Concordo. No fim, a reclamação é que ainda não houve muito esforço para lidar com Markdown rápido em Swift, mas a própria pessoa não está tentando contribuir com isso
  • 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
  • Concordo que, para layout de texto complexo, um webview faz sentido, mas não sei se, além da conveniência, é realmente necessário ir até Electron
    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 NSTextView e 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 simples
    • Quando é preciso dar suporte a vários sistemas, no fim das contas a simplicidade pesa muito
      Participei 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
    • Vejo isso como uma escolha pessoal. Seja tamanho do app ou uso de RAM, há quem esteja disposto a pagar o preço da conveniência, e parece que os milhões de usuários de apps como Visual Studio Code também concordam
      No fim, quero software melhor, não agradar gráfico do htop
      O 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
  • Um dos problemas é que quem faz software desenvolve em computadores e celulares entre os 0,1% melhores do mundo
    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
  • Fico curioso sobre como estão hoje as coisas no lado de GTK/Qt. Faz muito tempo que não mexo com GUI
    • Pelo que entendo, isso também deveria ser possível de implementar em Qt sem webview
      Só que parece que o autor não foi explorar esse lado aqui
  • Fico curioso sobre como seria uma comparação entre Electron e Flutter
    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
  • O autor de https://github.com/stevengharris/MarkupEditor sugere este texto como uma solução bastante boa entre as opções atualmente possíveis: https://blog.krzyzanowskim.com/2025/08/14/textkit-2-the-promised-land/
    • Mas o MarkupEditor não usa TextKit2, e sim WebView. O README também diz que o MarkupEditor interage com um documento HTML que usa uma única DIV com contentEditable, e que utiliza uma subclasse de WKWebView
      A 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 lista
      No 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