# Como a lista de desinstalação do Mole passou a abrir no clique

> Para onde ia o segundo ou mais de cada clique para desinstalar, o que foi para segundo plano e por que as 15.000 pastas temporárias do ChatGPT agora dividem uma linha.

Published: 2026-10-28

Ao clicar em um app na página de desinstalação do Mole, o lado direito ficava em branco por um instante, depois mostrava "Verificando", e só depois de meio segundo a um segundo os resíduos apareciam. O Xcode levava três a quatro segundos a cada clique, o ChatGPT seis, e rolar a lista expandida do ChatGPT travava. Eu queria ver para onde esse tempo ia de verdade, e aproveitei para olhar como alguns desinstaladores de código aberto lidam com o mesmo problema. As mudanças ficaram prontas em 5 de outubro e saíram no Mole 1.16.0; abaixo está o que medi na época e as escolhas que fiz.

## O lento não era o app

Eu esperava que apps maiores fossem mais lentos, e não eram: um utilitário pequeno de 6,6 MB com seis resíduos ainda levava cerca de 0,56 segundo no primeiro clique. A maior parte do tempo ia para algumas tarefas fixas que rodavam a cada clique. São medianas de três execuções em build Release no meu M5 Pro:

- Ler o catálogo de casks do Homebrew, um arquivo de 5,6 MB, levava cerca de 200 ms toda vez, só para saber se o app tinha sido instalado pelo Homebrew.
- A assinatura de código do app era validada, duas vezes, a cerca de 1 ms por MB de executável; o MindNode gastava 260 ms nisso a cada clique.
- A tarefa de verificação mais lenta era a lista de documentos recentes: cerca de 230 ms para 775 entradas, quase tudo conferindo caminhos um por um.

Alguns apps somavam um custo próprio. O recibo de instalação do Xcode tem 41 MB e lista 125.000 caminhos, e era lido de novo a cada clique. O ChatGPT deixa cerca de 15.000 pastas temporárias, e cada uma precisava ser conferida separadamente para saber se era mesmo dele.

## O que mudou

- O catálogo de casks é lido em segundo plano assim que a página de desinstalação abre, não no clique.
- O clique lê as informações de assinatura sem validá-las e fixa o app pela identidade do arquivo. A validação completa roda em segundo plano depois que a lista aparece, e precisa terminar antes de qualquer exclusão.
- Os documentos recentes são filtrados primeiro pelo nome; só os que batem passam pela verificação completa de propriedade.
- As raízes da biblioteca são listadas em paralelo, a identidade dos contêineres fica em cache por arquivo de metadados, e os prefixos de ID dos programas auxiliares são calculados uma vez por verificação.
- Os recibos de instalação ficam em cache por arquivo de recibo, então um segundo clique no Xcode não lê aqueles 41 MB de novo.
- Pastas temporárias cujo nome sozinho já prova a quem pertencem seguem um caminho rápido; a etapa de exclusão continua conferindo cada caminho.
- As verificações longas começam primeiro, e as centenas de tarefas pequenas ficam na fila atrás.
- Uma verificação iniciada ao passar o ponteiro para quando o ponteiro sai, e uma verificação iniciada antes de uma desinstalação não consegue mais gravar resultados antigos depois.

No caso da validação de assinatura, o mais fácil seria tirá-la. Em vez disso, eu a passei para depois do clique. Agora, quando a validação em segundo plano falha, o app em si é desinstalado do mesmo jeito, e só ficam para trás os tipos de resíduo encontrados pelas informações de assinatura, como contêineres associados pelo ID de equipe do desenvolvedor. O resultado os mostra como "Não foi possível verificar a assinatura do app", mantidos em vez de falhos. Um app trocado por outro depois da verificação continua sendo recusado.

## Quanto ficou mais rápido

Primeiro clique cerca de 1,5 segundo depois de abrir a página de desinstalação, build Release:

| App | Antes | Depois |
| --- | --- | --- |
| Shottr | 556 ms | 137 ms |
| MindNode | 1233 ms | 169 ms |
| Raycast | 716 ms | 171 ms |
| Parallels Desktop | 871 ms | 194 ms |
| VS Code | 584 ms | 232 ms |
| WeChat | 605 ms | 238 ms |
| Xcode | 3689 ms | 384 ms |
| ChatGPT | 6134 ms | 1530 ms |

A maioria dos apps comuns agora fica abaixo de 250 ms, então os resíduos aparecem de uma vez, sem mostrar "Verificando" antes. A validação de assinatura em segundo plano termina de 12 a 434 ms depois que a lista aparece.

## As quinze mil linhas do ChatGPT

Com os cliques rápidos, rolar um ChatGPT expandido ainda travava. Ele listava 15.175 linhas, e 15.143 delas eram pastas temporárias no formato `T/.com.openai.codex.XXXXXX`, 1,0 GB no total, algumas a mais a cada vez que o app abre. O Hina, um app que eu faço, era parecido: 323 de suas 344 linhas eram arquivos `Hina-<Suite>-<UUID>.plist` deixados por testes, 0,01 MB juntos. Nos dois casos, uma única forma com nome aleatório ocupava quase a lista inteira.

O número de linhas não era a única causa. A linha expandida reordenava todos os resíduos a cada redesenho, e passar o ponteiro redesenhava a linha inteira do app, então cada linha que deslizava sob um ponteiro parado disparava outra ordenação. Com os dados reais do ChatGPT, um redesenho caiu de 309 a 354 ms para 56 a 58 ms, o Hina de 33 a 36 ms para 17 a 19 ms, e a altura expandida do ChatGPT encolheu de 3200 pt para 1225 pt.

Agora várias linhas dividem uma só quando têm a mesma categoria, pasta, dono e seleção padrão, e os nomes diferem apenas em uma parte gerada pelo app: um sufixo aleatório, um UUID, uma longa sequência hexadecimal ou o horário de um relatório de falha. A linha compartilhada mantém o rótulo da categoria, mostra o caminho com `*` no lugar da parte que muda, seguido da quantidade de itens e do tamanho total, com uma única caixa de seleção, e não se expande. O ChatGPT caiu para 33 linhas em 13 categorias, o Hina para 24.

<figure class="blog-diagram">
  <picture>
    <source media="(max-width: 900px)" srcset="/img/blog/uninstall-leftovers-one-line-mobile.webp">
    <img src="https://mole.fit/img/blog/uninstall-leftovers-one-line.webp" width="1600" height="992" loading="lazy" alt="Os mesmos resíduos do ChatGPT antes e depois: antes, cada pasta temporária tem sua própria linha; depois, elas dividem uma linha com 15.143 itens e 1,02 GB, e os demais resíduos aparecem por categoria.">
  </picture>
  <figcaption>Os mesmos resíduos do ChatGPT, uma linha por pasta temporária antes, uma linha compartilhada depois.</figcaption>
</figure>

Pastas irmãs com nome próprio continuam cada uma em sua linha, como os sete caches do Electron do ChatGPT, `GPUCache`, `Code Cache`, `Crashpad` e os demais. Juntar essas também deixaria o Hina com umas sete linhas, o que já não parece uma limpeza completa; uma dúzia e pouco é a medida certa. Um nome com uma palavra de seis letras, como `T/<id>.helper`, também fica em linha própria, porque seis letras sozinhas não se distinguem de um sufixo aleatório.

Duas tentativas anteriores continuaram descartadas. Uma aninhava um grupo recolhível dentro da linha do app já expandida; foi testada em 30 de setembro e removida em 2 de outubro, porque colocava uma expansão dentro de outra e dividia caminhos parecidos entre o grupo e linhas soltas. A outra mostrava uma linha por categoria; foi usada a partir de 4 de setembro e desfeita uma semana depois, porque escondia locais diferentes atrás de uma só linha.

## Como outros desinstaladores fazem

O Pearcleaner lista cerca de 62 raízes em paralelo e compara por nome, sem prova de propriedade e sem cache; é rápido porque faz menos. O Tencent Lemon calcula os resíduos de todos os apps ao entrar na página e atualiza uma vez por dia, então os cliques são instantâneos, ao custo de uma grande verificação em segundo plano a cada visita, o que vai contra a regra do Mole de não adicionar trabalho residente. MangoDisk, Uninstally e o Mole CLI usam raízes fixas com concorrência limitada.

Nenhum deles tinha uma primitiva de baixo nível mais rápida que `getattrlistbulk` e `readdir`, que o Mole já usa. Também testei o Spotlight: cada consulta levava 0,3 a 0,4 segundo e deixava passar a maioria dos resíduos, encontrando um dos quatro do VS Code, enquanto o `searchfs` funciona no APFS mas leva cerca de 15 segundos por consulta. No fim, o trabalho se resumiu a tirar tarefas repetidas da verificação que o Mole já tinha. Para ver como ler essa lista de resíduos antes de apagar qualquer coisa, continue em [Resíduos de desinstalação no Mac: revise antes de apagar](https://mole.fit/pt-br/blog/mac-uninstall-leftovers-review-before-delete).

---

Canonical HTML page: https://mole.fit/pt-br/blog/mole-uninstall-review-speed
Blog index for agents: https://mole.fit/pt-br/blog/llms.txt
Site index for agents: https://mole.fit/llms.txt
