Performance web: como o claude.ai ficou 3x mais rápido

Performance web: como o claude.ai ficou 3x mais rápido

A performance web do claude.ai e do aplicativo desktop do Claude ficou cerca de três vezes melhor em um sprint de apenas duas semanas, em agosto de 2026. Neste artigo, analisamos como a equipe da Anthropic organizou esse trabalho, quais métricas usou e por que a medição virou o centro de toda a estratégia.

O caso interessa a qualquer time que cuida da performance web de uma aplicação em produção. Afinal, a maior parte das técnicas citadas não depende de IA, mas a forma como o agente acelerou o ciclo de otimização muda a escala do que um time consegue entregar.

O que é performance web e por que ela importa

Performance web é o conjunto de práticas que reduz o tempo entre uma ação do usuário e o resultado visível na tela. Na prática, isso envolve carregamento inicial, navegação, renderização e a fluidez da interface durante o uso.

Por isso, a Anthropic decidiu investir em performance web depois que os próprios usuários relataram lentidão no claude.ai.

O resultado chama atenção pelos números. No percentil 75, o tempo até a página ficar pronta para digitação caiu de 3,1 segundos para 0,55 segundo em um carregamento novo.

Além disso, iniciar uma nova sessão do Claude Code passou de 0,8 para 0,3 segundo. Já o carregamento de uma sessão do Claude Cowork na nuvem caiu de 2,6 para 0,73 segundo.

Segundo a equipe, essa economia soma dezenas de milhares de horas de espera por dia quando consideramos todos os usuários. Ou seja, um ganho de performance web em escala se traduz diretamente em tempo devolvido às pessoas.

O ponto de partida: quatro jornadas e treze medições

Antes do sprint, o time criou um canal no Slack com instruções permanentes para o Claude, rodando via Claude Tag. O agente recebeu a responsabilidade de monitorar deploys, avaliar a telemetria existente, manter dashboards e propor projetos de otimização.

Em seguida, o Claude analisou os dados de uso por meio do servidor MCP do Datadog. Dessa análise saíram quatro jornadas que concentram 95% da atividade dos usuários.

  • Abrir o aplicativo.
  • Iniciar uma conversa.
  • Carregar uma conversa existente.
  • Enviar uma mensagem.

Somando web, desktop e os diferentes produtos, essas jornadas viraram treze medições distintas. Para torná-las comparáveis, a equipe padronizou a instrumentação: cada medição começa em uma interação do usuário, termina quando o resultado aparece e separa o trabalho do cliente do trabalho do servidor.

Depois disso, o time listou cerca de vinte projetos, cada um ligado a uma jornada específica. O Claude estimou o impacto de cada projeto em milissegundos, e essas estimativas definiram as metas do sprint.

O detalhe curioso é que doze das treze metas caíram já no terceiro dia. Com isso, a equipe definiu metas de performance web mais ousadas e buscou novas métricas.

Medir para otimizar: a lição central sobre performance web

A principal conclusão do sprint cabe em uma frase: quando o Claude consegue medir algo, ele consegue melhorar esse algo. Por isso, a atividade de maior alavancagem passou a ser encontrar novas métricas.

Tradicionalmente, a medição era o passo zero de um projeto de performance web. O time adicionava uma métrica, esperava os dados chegarem e só então entendia o problema.

Com um agente trabalhando de forma contínua, a medição virou o primeiro passo da escalada. Assim que existia um número para bater, o Claude já começava a otimizar.

Contagem de instruções como métrica determinística

O tempo de relógio, conhecido como wall clock, é o que o usuário sente. No entanto, ele oscila demais entre execuções e não serve como barreira confiável em um pipeline de integração contínua.

Para contornar isso, um engenheiro sugeriu medir contagem de instruções de JavaScript. O Claude propôs rodar os benchmarks sob o Valgrind com a flag --predictable do Node.js, porque assim uma única execução gera um número estável.

Para caminhos que rodam no navegador, onde não há contagem de instruções, o agente sugeriu outras contagens determinísticas. Entre elas estavam commits do React por interação, chamadas de função via cobertura do V8, recálculos de estilo e mutações no DOM.

Mesmo assim, a equipe exigiu uma prova. Cada benchmark só ficaria no projeto se demonstrasse ganho real em tempo de relógio.

O teste aconteceu em dois caminhos quentes: a rotina que monta a árvore de mensagens de uma conversa e um scanner de linhas de status do Claude Code. No primeiro, um quarto das instruções vinha de buscas megamórficas em dicionário, resolvendo o mesmo ID de mensagem três vezes.

Em uma hora, o Claude reduziu as instruções em 48% e 31%, respectivamente. Ao mesmo tempo, o tempo de relógio caiu 78% e 44%, o que confirmou a correlação.

Ratchets no CI para proteger a performance web

Depois da validação, o time adicionou dois ratchets ao CI. Um ratchet funciona como uma catraca: o limite só pode descer, nunca subir.

Dessa forma, qualquer pull request que aumentasse a contagem de instruções daqueles caminhos falharia no CI. Além disso, um job diário baixava o teto sempre que a contagem diminuía.

Esse mecanismo resolve um problema antigo de performance web: ganhos que se perdem silenciosamente nas semanas seguintes. Com a catraca, cada melhoria vira o novo piso do projeto.

O ciclo de trabalho thread por thread

Todo o sprint aconteceu em um único canal, com vários engenheiros e o Claude participando das mesmas threads. Com o tempo, o trabalho se organizou em um ciclo bem definido.

  1. Alguém abre uma thread sobre um trecho lento, geralmente com um print ou uma gravação de tela.
  2. O agente rastreia o fluxo e encontra ou cria um benchmark que reproduz o problema.
  3. Com um resultado promissor em laboratório, ele abre pull requests pequenos, com mudanças visíveis atrás de feature flags.
  4. Após o deploy, o Claude lê os dados de campo de usuários reais.
  5. Se houve melhora, ele aperta o ratchet; caso contrário, desliga a flag e itera.
  6. Por fim, parte para o próximo ponto lento da mesma jornada.

Layout shift invisível nas métricas tradicionais

Um exemplo concreto mostra o ciclo funcionando. Uma gravação de tela revelou linhas da barra lateral surgindo depois do carregamento, o que deixava a página com aspecto instável.

Nenhum monitor de performance web detectava o problema. O Cumulative Layout Shift marcava cerca de 0,008 por deslocamento, muito abaixo do limite de 0,1 considerado bom.

Então, a equipe decidiu usar diretamente a Layout Instability API. O Claude criou um evento de telemetria que associa a origem de cada deslocamento a uma região nomeada e a uma fase do carregamento.

// Observa deslocamentos de layout e associa cada um a uma região da página
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    for (const source of entry.sources ?? []) {
      const region = source.node?.closest("[data-region]")?.dataset.region ?? "unknown";
      reportLayoutShift({ region, value: entry.value, time: entry.startTime });
    }
  }
});

observer.observe({ type: "layout-shift", buffered: true });

Além disso, o agente escreveu um teste de integração que segura os dados da barra lateral até depois da primeira pintura. O teste falhou em 20 de 20 execuções na branch principal e passou em 20 de 20 na correção.

Com o evento em produção, os dados mostraram que 31% dos carregamentos moviam algo depois que a página já estava utilizável. A partir daí, o Claude corrigiu as causas em lotes, como um cabeçalho atrasado e um cursor que deslizava quando o nome do usuário carregava.

Escalando a performance web horizontalmente

Quando o ciclo funcionou em uma thread, bastou abrir outras. Em alguns momentos, mais de cento e cinquenta threads rodavam ao mesmo tempo.

Em vez de encerrar uma thread após resolver o pedido original, o agente continuava buscando melhorias. Algumas threads chegaram a cinquenta ou até cem pull requests de otimização.

Cada nova medição revelou algo para corrigir. Veja alguns achados que mostram como a performance web degrada em pontos inesperados:

  • Um censo de hooks do React encontrou 6.900 hooks e 900 assinaturas de store renderizando a cada tecla digitada no campo de mensagem.
  • Um único seletor :root:has() adicionava 24 milissegundos a cada mudança no DOM.
  • Uma chamada esquecida de location.reload() gerava meio milhão de recarregamentos ocultos por dia.
  • Abas ociosas clonavam snapshots idênticos de cache no IndexedDB duas vezes por minuto, sempre na thread principal.

Na segunda semana, mais de duzentas mudanças chegavam à produção nos dias mais intensos. Inclusive, cerca de um terço dos pull requests trazia telemetria ou guardrails adicionais.

O caso dos caracteres fora do Latin-1

Um dos achados de performance web mais curiosos envolveu o realce de sintaxe em blocos de código. Em algumas respostas, destacar um bloco finalizado congelava a página por cerca de um segundo.

A causa estava em caracteres tipográficos comuns, como aspas curvas e traços longos. Quando o markdown continha qualquer caractere fora do Latin-1, o V8 armazenava a string inteira em UTF-16.

Com isso, todas as expressões regulares do realce rodavam no caminho mais lento, de dois bytes. A correção exigiu cerca de vinte linhas: copiar cada bloco de código para uma string de um byte antes do realce.

Depois da mudança, o primeiro bloco TypeScript da página caiu de 1 segundo para 0,35 segundo de bloqueio da thread principal.

Guardrails: como manter a performance web sem incidentes

Mais de três mil mudanças entraram em produção sem nenhum incidente visível para clientes e sem rollback. Esse número só faz sentido quando olhamos para as proteções definidas antes do sprint.

Toda mudança passava por revisão automatizada e por pelo menos uma aprovação humana. Além disso, testes unitários sempre vinham antes da otimização, e qualquer risco visível ficava atrás de uma feature flag de vida curta.

Nas duas semanas, o time criou quase duzentas flags. Mesmo assim, mais da metade já tinha sido removida no fim do sprint, porque o Claude classificava cada flag como kill switch ou rampa e retirava as seguras.

Também havia a preocupação com a erosão dos ganhos. Em um código que muda rápido, a performance web conquistada hoje pode desaparecer no próximo merge.

O composer estático e a pré-renderização do Chrome

Uma das otimizações mais visíveis foi o composer estático. O HTML inicial já traz uma cópia do campo de mensagem, e o React pinta por cima dessa cópia quando termina de inicializar.

Essa técnica é frágil por natureza, porque qualquer diferença de um pixel quebra a ilusão. Por isso, o agente criou dezenas de proteções específicas.

  • A marcação estática nasce da renderização do componente React real no jsdom, e um teste impede divergências.
  • Uma suíte compara a página estática com a versão React em catorze tamanhos de tela, com tolerância de 1 pixel.
  • Outro teste digita durante a troca e falha se alguma tecla se perder ou mudar de ordem.
  • Em campo, cada troca reporta deslocamentos com precisão de um décimo de pixel.

Ainda assim, nem tudo aparece em laboratório. Por isso, mudanças arriscadas chegavam primeiro aos funcionários, depois a 1% dos usuários e só então a todos.

Poucas horas após a liberação interna, um engenheiro notou o campo de mensagem descendo alguns pixels ao abrir uma nova aba. O Claude analisou a gravação e descobriu que a culpa era do próprio Chrome.

Em navegadores gerenciados por uma organização, a página de nova aba exibe um rodapé de 56 pixels. Quando o Chrome pré-renderiza o claude.ai a partir da barra de endereço, a página nasce mais baixa e cresce cerca de 100 milissegundos depois.

A solução fixou o layout durante esse redimensionamento. Além disso, a equipe adicionou um teste que simula o fluxo de pré-renderização.

O papel humano: ambição, gosto e direção

O ciclo era produtivo, mas não era autônomo. A equipe descreve três responsabilidades humanas que mantiveram o trabalho rápido, seguro e no rumo certo.

A primeira foi a ambição. Por padrão, o modelo tende a ser cauteloso: abre tickets, faz ressalvas e aumenta estimativas, então boa parte do trabalho inicial consistiu em incentivá-lo a agir com mais ousadia.

A segunda foi o gosto. Cada thread tinha um responsável humano, e o agente mostrava capturas de antes e depois para qualquer mudança perceptível.

Por exemplo, uma tabela deve preencher célula por célula ou esperar a linha completa? Da mesma forma, vale a pena um efeito de fade em cada palavra se ele consome um quinto do orçamento de cada frame?

A terceira foi a direção. As threads permaneciam estreitas, focadas em um benchmark ou jornada, e as pessoas decidiam prioridades, fusões e o momento de encerrar.

Em um caso, um pull request de 900 linhas recebeu uma recusa curta. O ganho de 2 milissegundos por envio não justificava manter um plugin de build adicional.

Um orçamento de 8 milissegundos por frame

Uma missão paralela resume bem o método de performance web do time. Ao demonstrar uma otimização de regex, o Claude anexou uma gravação com um medidor de frames por segundo calculado na própria página.

Então surgiu a pergunta: o teste estava limitado a 60 fps? De fato, o Chromium headless roda a 60 Hz por padrão, mas o agente configurou o controle de frames do DevTools para rodar a 120 Hz de forma determinística.

Com 120 Hz, cada frame tem um orçamento de 8,33 milissegundos. Assim, o Claude percorreu uma resposta longa frame a frame, cronometrando cada um para localizar os trechos lentos.

As correções incluíram memoizar blocos finalizados, mover a tokenização de blocos de código em crescimento para um worker e revelar tabelas célula por célula. Ou seja, o renderizador passou a tocar apenas no conteúdo que ainda muda.

Nessa única thread, quase sessenta pull requests entraram em produção. Respostas longas passaram a bloquear a thread principal por cerca de 200 milissegundos no total, contra 750 antes.

Além disso, o consumo de CPU caiu para cerca de um terço, e a renderização manteve 120 fps do início ao fim em um MacBook de 120 Hz. Hoje, esse teste roda todas as noites para detectar regressões.

Lições de performance web para o seu projeto

Mesmo sem o mesmo volume de threads, várias práticas do sprint funcionam em qualquer equipe. A seguir, reunimos as que mais se aplicam ao dia a dia.

  • Defina jornadas do usuário e meça cada uma do clique até o resultado na tela.
  • Prefira métricas determinísticas no CI, como contagens, e valide que elas acompanham o tempo real.
  • Use ratchets para que cada ganho de performance web vire o novo limite mínimo.
  • Coloque mudanças visíveis atrás de feature flags e faça rollouts graduais.
  • Quando uma métrica agregada parecer boa demais, desça para as APIs de baixo nível do navegador.

Do lado do backend, a lógica é a mesma. Se você trabalha com .NET, entender o garbage collector do C# ajuda a identificar alocações que viram pausas perceptíveis.

Conclusão sobre performance web

O sprint da Anthropic mostra que performance web deixou de ser um esforço pontual e passou a ser um processo contínuo, guiado por métricas. A frase que resume o projeto é simples: tudo que pode ser contado pode ser otimizado.

No entanto, o mérito não está só no agente. Os guardrails, os testes, as flags e as decisões humanas permitiram mais de três mil mudanças sem incidentes.

A própria equipe reconhece que ainda há espaço para melhorar o percentil 95, outras jornadas e conversas muito longas. Por isso, o canal continua ativo, e os ratchets seguem segurando cada ganho conquistado.

Para quem desenvolve aplicações web, a mensagem é clara. Comece medindo, porque sem um número para bater não existe otimização confiável.

FAQ

Quanto o claude.ai ficou mais rápido?

Em média geométrica das treze medições, o ganho foi de 3,1 vezes. O carregamento inicial da web foi o destaque, caindo de 3,1 para 0,55 segundo no percentil 75.

O que é um ratchet de performance?

É um limite no CI que só pode diminuir. Se um pull request piora a métrica, o build falha; se a métrica melhora, o limite desce automaticamente.

Por que usar contagem de instruções em vez de tempo?

Porque a contagem de instruções é determinística e não varia entre execuções. Assim, ela funciona como barreira confiável no CI, desde que acompanhe o tempo real.

O Claude trabalhou sozinho durante o sprint?

Não. Todo pull request teve revisão automatizada e aprovação humana, e as pessoas definiram metas, prioridades e decisões de experiência do usuário.

Essas técnicas servem para outros projetos?

Sim. Medir jornadas, criar benchmarks determinísticos, usar feature flags e proteger ganhos com ratchets funcionam em qualquer aplicação web.

Glossário

Termo Significado
Percentil 75 (p75) Valor abaixo do qual estão 75% das medições, usado para refletir a experiência da maioria dos usuários.
Wall clock Tempo real decorrido, medido como em um relógio, incluindo esperas e ruídos do sistema.
Benchmark Teste que mede o desempenho de um trecho de código ou fluxo em condições controladas.
Ratchet Mecanismo no CI em que o limite de uma métrica só pode diminuir ao longo do tempo.
Feature flag Chave que liga ou desliga uma funcionalidade em produção sem novo deploy.
Cumulative Layout Shift (CLS) Métrica do Core Web Vitals que soma os deslocamentos inesperados de layout.
Layout Instability API API do navegador que expõe cada deslocamento de layout e os elementos envolvidos.
Valgrind Ferramenta de instrumentação capaz de contar instruções executadas por um programa.
Hot path Caminho de código executado com alta frequência, onde pequenas melhorias têm grande impacto.
Thread principal Thread do navegador responsável por executar JavaScript, calcular layout e pintar a tela.
Pré-renderização Recurso do Chrome que carrega uma página em segundo plano antes de o usuário confirmar a navegação.
Memoização Técnica que guarda o resultado de um cálculo para evitar repeti-lo.

Fontes