
Caso 05E-commerce de produtos digitais
Loja FPV
A loja onde vendo o que faço para piloto de drone. Toca som e vídeo antes da compra, e mesmo assim, na mesma rede lenta, o maior elemento da página caiu de 5,7 s para 2,4 s.
Ver a diferença- Meu papel
- Produto, preço e revisão de cada tela. O código é do agente.
- Período
- 30 de outubro a 4 de novembro de 2026, 45 commits
- Situação
- No ar, vendendo o RASANTE
- Stack
- Next.js 16, React 19, CSS Modules e Gumroad
Em 30 segundos
O RASANTE precisava de um lugar para ser vendido. Em seis dias, com agentes de código, fiz a vitrine e a página de venda dentro do meu próprio site. A compra acontece sem sair da página.
Quem compra som quer ouvir antes, e a página que toca som e vídeo é justamente a que fica pesada. Este caso é sobre esse conflito, e sobre cobrar do agente número medido em vez de impressão.
- 2,4 s
- até o maior elemento em rede lenta no celular. Eram 5,7 s
- 0,8 s
- até a primeira pintura, na mesma rede. Eram 2 s
- 100
- em acessibilidade, boas práticas e SEO no Lighthouse, nas duas páginas
- 223
- capturas da loja no histórico visual, guardadas a cada mudança
Duas páginas e uma compra
A vitrine mostra o que existe. A página de venda faz o resto. O checkout abre por cima dela, sem criar conta.


Três decisões
O pagamento fica no Gumroad
Os dados do cartão não passam pelo meu site. O preço disso é a cobrança sair em dólar, sem Pix nem boleto, e a página avisa antes do clique.
SPEC.md
Sempre um botão de compra à vista
No celular, uma barra fixa aparece quando nenhum outro botão de compra está na tela, e some de novo em cima da oferta.
SPEC.md
As fontes moram no repositório
O next/font/google derrubou dois deploys quando o Google Fonts entregou uma fonte em outro endereço. Agora o build não depende de ninguém.
BACKLOG.md
Quem compra som quer ouvir
Tudo na página existe para a pessoa ouvir e ver o que vem no zip antes de pagar.




O conteúdo não é digitado. As prévias, a lista de arquivos e a timeline do filme saem do repositório do pack, e um teste confere se a última versão anunciada bate com o que está no zip.


A timeline foi a parte mais delicada. A agulha segue o quadro que está na tela, no mesmo relógio do som, e os 76 KB de dados só baixam com o filme perto da tela. Com brotli, viram 28 KB, e o tempo de carregamento da página não mudou.

A mesma página, na mesma rede lenta
Toda essa mídia tinha um preço. Aqui estão as duas versões carregando lado a lado, filmadas no mesmo celular emulado.
Texto na tela, sem a imagem
Maior elemento na tela
2,6 s
Antes
Depois
- Primeira pintura
- Maior elemento
| Medida | Antes | Depois |
|---|---|---|
| Primeira pintura | 1,98 s | 0,80 s |
| Maior elemento | 5,70 s | 2,44 s |
A diferença não veio de um truque só. Cada atraso apareceu numa medição, virou uma correção, e a correção ganhou um teste para não voltar.
| O que a medição achou | Custo | O que mudou |
|---|---|---|
| O maior elemento era o vídeo em loop do topo | Mais de 6 s no celular | O quadro vem no HTML como imagem, no recorte da tela. O vídeo entra por cima depois que a página carrega. |
| Os links para a home faziam prefetch do Three.js | 568 KB em toda página da loja | Esses links não fazem mais prefetch. |
| Os cartazes de vídeo baixavam mesmo longe da tela | 189 KB | Só baixam com o vídeo a uma tela de distância. |
| A primeira pintura esperava o arquivo de CSS | 2,1 s em vez de 0,75 s, em rede lenta | O CSS vai embutido no HTML. |
| Com o CSS no HTML, o topo saltava quando o HTML chegava em pedaços | CLS de 0,27 a 0,46 | Um link rel="expect" segura a pintura até o fim do topo chegar. |
| O vídeo ficava 51 px² maior que o quadro em algumas telas | LCP de 4,3 s em vez de 2 s, em parte das cargas | O vídeo fica 1 px mais baixo que o quadro. |
O atraso que o Lighthouse não mostrava
Depois de tudo isso, a vitrine ainda levava 4,3 s em vez de 2 s em parte das cargas. O Lighthouse não acusava nada, e no Mac, com celular emulado, a primeira pintura dele cai em degraus de 1 s, o que esconde ganho e perda menores. Quem mostrou foi um script novo do agente, que lê a Performance API da própria página e lista quem foi o maior elemento em cada carga.
A resposta era um arredondamento. Em algumas telas, o vídeo ficava 51 px² maior que o quadro, e o Chrome passava o título de maior elemento para o primeiro quadro do vídeo, segundos depois. Agora o vídeo fica 1 px mais baixo, e um teste confere as duas áreas em oito tamanhos de tela.
| Versão | Quando | Elemento | Área em px² |
|---|---|---|---|
| Antes | 1.988 ms | span | 94.770 |
| Antes | 5.692 ms | video | 328.770 |
| Depois | 792 ms | span | 94.770 |
| Depois | 2.420 ms | img | 328.770 |
| Página | Desempenho | Acessib. | Práticas | SEO | LCP |
|---|---|---|---|---|---|
| Vitrine | 92 | 100 | 100 | 100 | 3,2 s |
| Página de venda | 95 | 100 | 100 | 100 | 2,8 s |
O que só aparece no iPhone
No Chromium, a tela cheia parecia funcionar. No iPhone só o player nativo abre, e a API padrão finge que deu certo.
Por isso a loja tem um teste que abre o Safari de verdade, num simulador de iPhone, no iOS 18.6 e no 26.0. Os toques vão pelo WebDriver, porque o clique em elemento do safaridriver não chega à página no simulador. O teste confere o que quem visita veria: o play do demo abre o player nativo e o vídeo anda; ao sair, o botão largo continua lá e reabre; no fim, o player fecha e a cartela aparece.
O que fica testado
Uma loja quebra em silêncio. Quem não consegue comprar não avisa, só vai embora.
test:store
1.015 linhas. Botões de compra, player, demo, pastas, filme, timeline, oferta, barra fixa e tela cheia, no computador e no celular.
test:seo
356 linhas. Título, canonical, Open Graph e dados estruturados, conferidos no HTML que chega sem JavaScript.
verify-store-iphone
O Safari em simulador de iPhone, com toques de verdade, em duas versões do iOS.
measure-store-speed
Primeira pintura e maior elemento em três redes, com o elemento que ficou com o LCP em cada carga.
Nenhum teste sai da máquina. O gumroad.js responde com conteúdo vazio, mas o pedido fica registrado, então dá para provar que todo botão de compra leva ao checkout sem tocar na loja real. Com a página no ar, o teste de resultados avançados do Google validou 2 itens na vitrine e 5 na página de venda.
Como dividi o trabalho com a IA
O agente escreve rápido e acha causa quando recebe um número. O que não vem dele é decidir o que o número precisa ser.
Ficou com a IA
- Escrever as páginas, os players, o filme com a timeline e a ligação com o Gumroad.
- Achar cada atraso com script próprio e provar a correção com teste.
- Guardar a captura de cada mudança nos três tamanhos de tela.
Ficou comigo
- Decidir o que se vende, por quanto e o que a página promete.
- Revisar tela por tela e mandar refazer, até a frase do topo.
- Filmar os voos que a página mostra.
O que ainda falta
O que a loja ainda não resolve e o que ainda não tenho para mostrar.
- Sem Pix nem boleto. Para quem compra no Brasil isso é barreira, e por enquanto a resposta é só avisar antes.
- A vitrine ainda fica com o maior elemento em 3,2 s no Lighthouse, acima dos 2,5 s do Core Web Vitals.
- Medi em celular emulado. Falta repetir num aparelho físico, numa rede de verdade.
- Os testes param na porta do Gumroad. O pagamento em si não entra no teste automático.
- A vitrine tem um produto. A estrutura aceita mais, mas só vai ser posta à prova quando o segundo existir.
- A loja está no ar há poucos dias. Ainda não tenho número de venda para mostrar.








