Voltar para o blog
post.md

Como usar um agente de IA para pensar em performance no frontend

Veja como orientar um agente de IA a medir e melhorar a performance de frontends React ou Vue com SSR, cache, lazy loading e validação antes e depois.

IAAgentes de códigoPerformance frontendCore Web VitalsSSRCacheLazy loadingReactVue

Um agente de IA ajuda mais na performance quando mede antes de alterar. SSR, cache e lazy loading são hipóteses: o ganho só existe quando uma comparação reproduzível confirma o resultado.

Performance não começa na técnica

Quando uma aplicação começa a receber mais acessos, é comum a conversa virar uma lista conhecida: usar SSR, adicionar lazy loading, configurar cache, reduzir o bundle, otimizar imagens ou colocar uma CDN na frente. Todos esses pontos podem ajudar, mas eles não resolvem o mesmo problema.

SSR pode melhorar a entrega do conteúdo inicial e, ao mesmo tempo, aumentar o trabalho do servidor se cada acesso exigir uma nova renderização. Lazy loading pode reduzir o JavaScript inicial e piorar o carregamento se esconder justamente o conteúdo principal. Cache pode reduzir latência e carga no origin, mas também pode entregar informação antiga ou compartilhar uma resposta personalizada no lugar errado.

Por isso, a pergunta útil não é “qual otimização está faltando?”. É “qual comportamento está lento, qual evidência mostra isso e qual é o menor experimento capaz de melhorar esse sinal?”. É nessa investigação que um agente de IA pode ser realmente útil.

“Muitos acessos” esconde dois problemas diferentes

1. A experiência de cada usuário

A primeira pergunta é: a página aparece, estabiliza e responde rapidamente para quem está usando? Aqui entram LCP, INP e CLS — o conjunto atual de Core Web Vitals —, além da quantidade de JavaScript enviado e executado, tarefas longas no main thread e tamanho e prioridade de imagens, fontes e outros recursos.

Ferramentas de laboratório são úteis durante o desenvolvimento, mas não substituem dados de campo. O Lighthouse, por exemplo, não mede o INP real porque não existe uma sequência representativa de interações de usuários naquele teste. O TBT pode sinalizar bloqueio da thread principal, mas não deve ser apresentado como se fosse a mesma métrica.

2. O trabalho repetido a cada acesso

A segunda pergunta é: quanto trabalho a aplicação, o servidor e as APIs repetem para atender cada visita? Aqui entram TTFB, taxa de cache hit, requisições que chegam ao origin, renderizações por acesso, chamadas duplicadas, volume transferido, saturação, fila, timeout e taxa de erro sob carga.

Uma página pode ter bom score de laboratório e ainda pressionar o servidor porque consulta e renderiza os mesmos dados em toda requisição. O contrário também acontece: uma página estática pode absorver muito tráfego na CDN e continuar enviando JavaScript demais para um celular de entrada. Lighthouse não é teste de carga, e teste de carga não substitui Core Web Vitals.

Fluxo de auditoria em que um agente de IA cruza métricas da experiência no navegador com cache, renderização e carga no servidor.
Performance percebida e capacidade sob tráfego são problemas relacionados, mas precisam de métricas e intervenções diferentes.

O prompt “deixe meu site mais rápido” é pequeno demais

Um agente de código pode ler componentes, configurações, dependências e resultados do build, além de controlar um navegador. Mesmo assim, um pedido genérico pode levá-lo a refatorar uma área irrelevante, espalhar memoização sem profiling, dividir componentes pequenos demais, atrasar a imagem de LCP ou transformar uma rota em SSR sem considerar cache e custo do origin.

snippettext
1medir2  -> localizar o gargalo3  -> formular uma hipótese4  -> mudar uma coisa5  -> medir novamente6  -> decidir

O agente não deveria começar escrevendo código. Ele deveria começar construindo uma linha de base e deixando claro o que foi medido, o que foi inferido e o que ainda não pôde ser verificado.

O contexto mínimo para uma boa auditoria

  • Framework, versão e comando de build de produção.
  • Forma de deploy, CDN, origin e rotas mais importantes.
  • Quais páginas são públicas, personalizadas ou autenticadas.
  • Frequência de atualização dos dados e regras de validade.
  • Dispositivos e redes predominantes, quando esse dado existir.
  • Comportamentos, SEO e acessibilidade que não podem mudar.
  • Métricas de campo e orçamento de performance já disponíveis.
snippettext
1Para cada conclusão, marque:2- medido3- inferido4- não verificado

Sete pontos simples que o agente pode investigar

O objetivo não é aplicar os sete. É descobrir quais atacam o gargalo medido com o menor risco.

1. Escolher a renderização por rota

SSR, SSG e CSR não deveriam ser decisões globais tomadas apenas pelo nome da arquitetura. Um artigo ou uma landing page pouco volátil pode ser estático. Uma página pública atualizada a cada poucos minutos pode aceitar revalidação. Uma área autenticada talvez precise de renderização dinâmica. Uma tela muito interativa pode manter partes no cliente sem obrigar toda a rota a começar como uma SPA vazia.

Pergunta para o agente: quais partes desta rota realmente dependem da requisição atual e quais poderiam ser estáticas, cacheadas ou revalidadas?

2. Configurar cache de acordo com a validade

Cache pode existir no navegador, na CDN, no HTML renderizado, nas chamadas de dados e nos assets versionados. Arquivos com hash normalmente aceitam cache longo e immutable; HTML costuma exigir outra política. Respostas autenticadas ou personalizadas precisam de cuidado extra para nunca se tornarem públicas em um cache compartilhado.

  • O que será armazenado e por quanto tempo continua válido?
  • A resposta é pública ou privada?
  • Qual evento exige invalidação?
  • O que acontece quando o cache expira?
  • Como serão medidos cache hit e tráfego poupado no origin?

3. Aplicar lazy loading somente ao que não é crítico

Modal, editor, mapa, gráfico pesado, player abaixo da dobra e uma rota que talvez nem seja visitada são bons candidatos. A imagem ou o conteúdo que forma o LCP não são: o recurso principal precisa ser descoberto cedo e receber prioridade adequada. Adie o que não participa da primeira experiência, mas preserve o caminho do conteúdo principal.

4. Enviar e executar menos JavaScript

O agente pode procurar dependências pesadas para tarefas pequenas, imports que prejudicam tree-shaking, bibliotecas carregadas em todas as rotas, fronteiras client-side amplas, componentes estáticos hidratados sem necessidade, scripts de terceiros no caminho crítico e código não utilizado no bundle inicial. Em React e Next.js, vale revisar o alcance de use client. Em Vue e Nuxt, vale observar o custo da hidratação e de plugins executados no início.

5. Revisar imagens, fontes e estabilidade visual

Dimensões ausentes, arquivos maiores do que o tamanho exibido, falta de variações responsivas, compressão insuficiente, imagem de LCP sem prioridade e mídia fora da tela carregada cedo são oportunidades frequentes. Largura, altura ou proporção reservada ajudam a reduzir CLS. Muitas famílias, pesos e estilos de fonte também aumentam transferência e podem atrasar texto.

6. Eliminar waterfalls e requisições duplicadas

snippettext
1buscar usuário2  -> buscar permissões3  -> buscar catálogo4  -> buscar recomendações

Se catálogo e recomendações não dependem de permissões, parte dessas chamadas pode acontecer em paralelo. O agente também pode encontrar uma busca feita no servidor e repetida durante a hidratação, componentes irmãos consultando o mesmo recurso, payloads maiores do que a tela usa e prefetch agressivo que gera tráfego sem retorno.

7. Reduzir renderizações e listas caras depois de medir

Nem todo gargalo aparece no carregamento. Uma busca pode travar ao digitar, um filtro pode atualizar centenas de componentes e uma tabela pode criar milhares de nós no DOM. Profiler e painel de performance ajudam a encontrar props instáveis, cálculos repetidos, listas sem paginação ou virtualização e tarefas longas. Memoização entra depois da evidência, não antes dela.

Um exemplo prático em React e Vue

Imagine um catálogo público com título, imagem principal, produtos atualizados a cada poucos minutos, filtros interativos, um gráfico comparativo aberto sob demanda e avaliações abaixo da primeira tela. Uma hipótese inicial pode manter a estrutura estática, revalidar a lista dentro da janela aceita, deixar filtros no cliente e carregar gráfico e avaliações somente quando necessários.

CompareButton.tsxtsx
1'use client';23import dynamic from 'next/dynamic';4import { useState } from 'react';56const ProductChart = dynamic(() => import('./ProductChart'), {7	loading: () => <p>Carregando comparação...</p>,8});910export function CompareButton() {11	const [showChart, setShowChart] = useState(false);1213	return (14		<section>15			<button onClick={() => setShowChart(true)}>Comparar produtos</button>16			{showChart ? <ProductChart /> : null}17		</section>18	);19}

No exemplo com Next.js, o ganho não vem apenas de usar dynamic. Ele vem de o gráfico pesado não participar do carregamento inicial e talvez nunca ser baixado por quem não abre a comparação. O agente ainda deve confirmar a separação do chunk no build, revisar o alcance de use client e preservar a prioridade da imagem principal.

CompareButton.vuevue
1<script setup lang="ts">2import { defineAsyncComponent, ref } from 'vue';34const showChart = ref(false);5const ProductChart = defineAsyncComponent(() => import('./ProductChart.vue'));6</script>78<template>9	<section>10		<button @click="showChart = true">Comparar produtos</button>11		<ProductChart v-if="showChart" />12	</section>13</template>

No Vue, defineAsyncComponent expressa a mesma intenção. Em Nuxt, um componente autoimportado pode usar o prefixo Lazy e versões atuais também oferecem hidratação adiada. O detalhe da API muda; a intenção continua sendo preservar conteúdo crítico, dividir código opcional, evitar hidratação desnecessária e confirmar o resultado no build e no navegador.

Um prompt melhor para a auditoria

prompt-auditoria.txttext
1Atue como um agente de diagnóstico de performance frontend.23Objetivo:4Identificar as três oportunidades de maior impacto para a rota [ROTA],5considerando a experiência por visita e o trabalho repetido por acesso.67Contexto:8- stack e versões: [REACT/NEXT OU VUE/NUXT]9- deploy: [PLATAFORMA, CDN E ORIGIN]10- tipo de rota: [PÚBLICA, PERSONALIZADA OU AUTENTICADA]11- atualização dos dados: [FREQUÊNCIA]12- comando de build: [COMANDO]13- comportamento que não pode mudar: [RESTRIÇÕES]1415Sucesso significa:16- executar o build de produção e registrar uma linha de base;17- inspecionar bundle, waterfall, HTML inicial, hidratação, imagens,18  fontes, scripts de terceiros e headers de cache;19- separar fatos medidos, inferências e dados ausentes;20- avaliar SSR/SSG/CSR, lazy loading, cache e redução de JavaScript21  somente quando atacarem o gargalo observado;22- priorizar no máximo três hipóteses por impacto, confiança, esforço e risco;23- indicar para cada hipótese a métrica afetada e como validar;24- não alterar código nesta etapa.2526Restrições:27- não tratar uma nota única do Lighthouse como prova suficiente;28- não usar TBT como se fosse INP de campo;29- não inventar ganhos percentuais;30- não aplicar lazy loading ao elemento de LCP sem justificativa;31- não cachear respostas personalizadas em cache compartilhado;32- não recomendar SSR como solução universal.3334Saída:351. resumo da linha de base;362. gargalos com evidência;373. tabela de hipóteses priorizadas;384. plano do menor experimento útil;395. lacunas que exigem dados de produção.

Implemente uma hipótese por vez

prompt-implementacao.txttext
1Implemente somente a hipótese aprovada: [HIPÓTESE].23Preserve comportamento, acessibilidade, SEO e atualização correta dos dados.4Execute o mesmo build e repita a mesma medição nas condições da linha de base.56Ao finalizar, informe:7- arquivos alterados;8- baseline e resultado de cada métrica relevante;9- variação entre execuções;10- efeitos colaterais ou riscos;11- decisão recomendada: manter, revisar ou descartar.1213Se a evidência não mostrar melhora consistente, não apresente a mudança como ganho.

Separar diagnóstico e implementação evita misturar várias mudanças e depois não saber qual delas alterou o resultado. Também permite rejeitar uma solução tecnicamente interessante quando ela não produz ganho suficiente naquele contexto.

Plugin ou skill: o que realmente ajuda?

Para esse trabalho, eu não começaria por um plugin genérico. O agente precisa principalmente de acesso ao repositório, ao terminal, ao build e a um navegador. Um plugin do provedor de infraestrutura pode complementar a análise quando expõe métricas reais de CDN, cache ou edge, mas não substitui profiling, dados de campo nem teste controlado.

Uma skill local chamada frontend-performance-audit pode ser mais útil porque preserva o método: detectar a stack, gerar o build, medir a rota, inspecionar HTML, waterfall, hidratação e cache, separar fatos de hipóteses, implementar uma mudança aprovada e produzir o relatório antes/depois. Referências específicas para React/Next, Vue/Nuxt e SPA com Vite podem ficar dentro da mesma skill.

O ganho da skill não é adicionar uma capacidade secreta ao modelo. É tornar a auditoria repetível para que a próxima revisão não dependa de lembrar o prompt inteiro.

Como saber se a mudança realmente ajudou

Rede, temperatura do dispositivo, processos em segundo plano, cache aquecido, localização e carga do servidor criam variação. Uma comparação confiável registra build, rota, cenário, dispositivo, rede, estado do cache, quantidade de execuções, mediana, dispersão e a diferença entre laboratório e campo.

O resultado não deveria ser apenas uma nota geral. Uma mudança pode melhorar LCP e aumentar JavaScript; reduzir o bundle inicial e criar atraso quando uma função importante é aberta; diminuir TTFB com cache e manter conteúdo antigo por tempo demais. O trade-off precisa aparecer no relatório.

Performance budget como proteção contra regressão

  • Tamanho máximo para o chunk inicial de uma rota.
  • Limite para a imagem principal e JavaScript de terceiros.
  • Alerta quando o bundle cresce além da tolerância definida.
  • Revisão obrigatória para novas fronteiras client-side.
  • Verificação dos headers de cache em assets públicos.

Os números não devem ser inventados pelo agente. Eles precisam nascer da aplicação, do público e da linha de base. Depois disso, o agente pode revisar diffs e apontar regressões antes que elas se acumulem.

Checklist prático

  • Qual rota é mais importante e o build analisado é de produção?
  • O problema é carregamento, interação ou capacidade sob tráfego?
  • Existe dado de campo ou apenas laboratório?
  • Qual elemento forma o LCP e quanto JavaScript chega primeiro?
  • Existe código opcional carregado cedo demais?
  • SSR está fazendo trabalho novo em toda visita?
  • Quais rotas poderiam ser estáticas ou revalidadas?
  • HTML, APIs e assets possuem políticas de cache coerentes?
  • Alguma resposta personalizada pode cair em cache compartilhado?
  • Existem requisições duplicadas, waterfalls ou listas grandes?
  • Qual métrica deve melhorar e como o mesmo teste será repetido?
  • Qual resultado faria a hipótese ser descartada?

Limites e ressalvas

Este artigo não substitui profiling, teste de carga, RUM, documentação do framework nem conhecimento sobre o deploy real. Os snippets mostram intenção arquitetural; APIs de renderização, cache, revalidação e hidratação mudam entre versões de Next.js e Nuxt e precisam ser conferidas antes da implementação.

Não existe orçamento universal. Uma página editorial, um dashboard interno e um editor gráfico possuem públicos e prioridades diferentes. Nem toda recomendação do Lighthouse precisa virar tarefa, nem toda rota dinâmica deveria ser estática e nem todo cache é seguro. Nenhum agente conhece o comportamento real dos usuários quando esse dado não está disponível.

Conclusão

Um agente de IA consegue navegar pelo projeto, identificar rotas, analisar dependências, executar o build, inspecionar a página e relacionar código com métricas. O ganho não vem de pedir “deixe tudo mais rápido”. Vem de oferecer contexto e exigir evidência.

Quando o prompt pergunta qual rota é crítica, se o problema está no navegador ou no trabalho repetido pelo servidor, qual métrica precisa mudar e como o teste será repetido, o agente deixa de ser um gerador de sugestões e passa a participar de um experimento técnico. Esse é um uso criterioso da IA: ajudar a medir, comparar e decidir.