vercel-react-best-practices (vercel-labs/agent-skills)
Aplica as diretrizes de desempenho de React e Next.js da Vercel a componentes, busca de dados e bundles.
Boas práticas de React da Vercel: eleva uma otimização de Next.js de 2.3 para 3.6/5, mas a versão de uma frase chega a 4.6 com 75% dos tokens
Codex CLI · gpt-6-astra
24.3 / 30
Ganho sobre sem skill: +0.85 · Situacional · 18 execuções
Situacional: o ganho +0.85 está abaixo de +1.0. Para ser recomendado, é preciso total de 22/30, qualidade da saída de 3.5 e ganho de +1.0.
SOTA
AprovadoTestado com Codex.
Cobre Codex, Claude Code
Codex CLI 0.166 (nível SOTA): 18 execuções avaliadas. Uma aprovação aqui também vale para o Claude Code pela nossa regra de níveis; ela não diz nada sobre o segundo nível.
Notas
Cada dimensão vai de 0 a 5, e as seis somam o total de 30. 5 é melhor em todas as dimensões. Custo 5 significa barato e rápido. Instalação 5 significa fácil.
- Confiabilidade do acionamento
- 5.0
- Ganho sobre sem skill
- 2.9
- Qualidade da saída
- 4.4
- Custo de tokens e tempo
- 3.0
- Instalação e portabilidade
- 4.0
- Segurança
- 5.0
Revisão de segurança
SeguroVarredura estática: 6 CRÍTICO / 0 ALTO / 0 MÉDIO. Revisão manual: seguro para executar em sandbox sem rede (achados do scanner explicados). Uma varredura limpa não prova que a skill é segura.
Instalar
npx skills@latest add vercel-labs/agent-skills --skill react-best-practices
Commit fixado: 1a2c79d4e6c4a2283dc2c614b6538cbe1ed5ca62
Testado: 2026-11-02
O que testamos
- Revisão de performance de um dashboard — Revise OrdersDashboard.tsx e page.tsx (um app Next.js 15) em busca de problemas de performance. Liste-os do mais sério para o menos, cada um com o arquivo e o que mudar. Não altere nenhum arquivo. Escreva a lista na sua resposta final.
- Otimizar o componente do dashboard no próprio arquivo — Otimize OrdersDashboard.tsx para performance. Edite o arquivo diretamente, mantenha o comportamento e as props do componente iguais. (Não há rede nem npm install; não tente rodar.)
- Escrever uma página de servidor do dashboard — Escreva app/dashboard/page.tsx, um server component do Next.js 15 (App Router). Para o usuário logado (getSession() de '@/lib/auth' retorna { userId }), ela precisa de getProfile(userId), getRecentOrders(userId) e getRecommendations(userId) de '@/lib/data'…
Prós
- Eleva a nota média de 3.57 para 4.43 em relação ao grupo sem skill (+0.85).
- A skill foi acionada sem ser nomeada: o arquivo da skill foi lido em 6/6 execuções de tratamento.
Contras
- Um prompt de uma frase marcou 4.73, contra 4.43 com a skill (-0.30).
- Usa 1.53x os tokens do grupo sem skill.
- n=2 por tarefa por braço; diferenças abaixo de cerca de 1 ponto são ruído.
Avaliação
Codex CLI 0.166 (gpt-6-astra, raciocínio baixo) em uma máquina de teste Mac, com um projeto temporário novo e HOME/TMPDIR/caches temporários a cada execução, skill instalada (tratamento) ou ausente (grupo de controle) ou ausente com o requisito central da skill comprimido em uma frase anexada ao prompt (grupo prompt de uma frase), 2 execuções por grupo por tarefa, rede desligada, gravações em /tmp bloqueadas. Os prompts nunca mencionam a skill (exceto pelo texto indicado abaixo). Três tarefas em fixtures pequenos de Next.js 15: revisar um componente de dashboard e uma página quanto a performance (11 problemas plantados, listados do mais sério para o menos); otimizar o componente no próprio arquivo (10 checagens: Promise.all, imports diretos em vez de barrel, nenhum import de lodash inteiro, next/dynamic para um editor pesado, Row elevado para fora do componente, lista derivada em vez de setFiltered em um efeito, sem orders.length &&, inicializador de estado preguiçoso, busca em Map, listener de scroll passivo); escrever uma página de servidor para uma chamada de dados lenta e duas rápidas.
Comparação entre os braços
| Braço | Nota média (0-5) | Tokens por execução |
|---|---|---|
| Sem a skill | 3.57 | 67k |
| Prompt de uma frase | 4.73 | 77k |
| Com a skill | 4.43 | 103k |
Medido com Codex CLI em 18 execuções, com pontuação por verificações baseadas em regras e sem juiz LLM. Total 24.3 / 30, veredito Situacional.
Veredicto: Situacional (24.3 / 30). Fonte: vercel-labs/agent-skills, skills/react-best-practices, fixado no commit 1a2c79d. Instalação: npx skills@latest add vercel-labs/agent-skills --skill react-best-practices. Licença: MIT (LICENSE do repositório).
O que é
A skill vercel-react-best-practices da vercel-labs/agent-skills (diretório react-best-practices): 70 arquivos Markdown de regras, agrupados por impacto (cascatas de requisições, tamanho do bundle, desempenho no servidor, busca de dados no cliente, re-renderizações, renderização, desempenho de JS, padrões avançados), mais um AGENTS.md compilado. O SKILL.md é um índice; o agente carrega as regras de que precisa. Nenhum script.
Como testamos
Codex CLI 0.166 (gpt-6-astra, raciocínio baixo) em uma máquina de teste Mac, com um projeto temporário novo e HOME/TMPDIR/caches temporários a cada execução, skill instalada (tratamento), ausente (controle) ou ausente com o requisito central da skill comprimido em uma frase anexada ao prompt (grupo de uma frase), 2 execuções por grupo por tarefa, rede desligada, gravações em /tmp bloqueadas. Os prompts nunca mencionam a skill (exceto pelo texto indicado abaixo).
Três tarefas em pequenos fixtures Next.js 15: analisar um componente e uma página de dashboard em busca de desempenho (11 problemas plantados, listados do mais sério para o menos); otimizar o componente no próprio local (10 verificações: Promise.all, importações diretas em vez de um barrel, nenhum import de lodash inteiro, next/dynamic para um editor pesado, Row elevado para fora do componente, lista derivada em vez de setFiltered em um efeito, nada de orders.length &&, inicializador de estado preguiçoso, busca em Map, listener de scroll passivo); escrever uma página de servidor para uma chamada de dados lenta e duas rápidas.
- Análise de desempenho de um dashboard — Analise OrdersDashboard.tsx e page.tsx (um app Next.js 15) em busca de problemas de desempenho. Liste-os do mais sério para o menos, cada um com o arquivo e o que mudar. Não altere nenhum arquivo. Escreva a lista na sua resposta final.
- Otimizar o componente do dashboard no próprio arquivo — Otimize OrdersDashboard.tsx para desempenho. Edite o arquivo no próprio local, mantenha o comportamento e as props do componente iguais. (Não há rede nem npm install; não tente executar.)
- Escrever uma página de servidor do dashboard — Escreva app/dashboard/page.tsx, um componente de servidor Next.js 15 (App Router). Para o usuário logado (
getSession()de '@/lib/auth' retorna{ userId }), ele precisa degetProfile(userId),getRecentOrders(userId)egetRecommendations(userId)de '@/lib/data'…
A pontuação é programática (testes ocultos / identificação de problemas plantados / verificações de restrições / renderização + OCR quando aplicável), de 0 a 5 por execução. Nenhum juiz LLM decidiu qualquer pontuação.
Resultados
A frase única dada ao terceiro grupo: "Corrija o desempenho de React/Next.js nesta ordem: elimine cascatas de requisições (inicie buscas independentes juntas com Promise.all e transmita as partes lentas com Suspense), reduza o tamanho do bundle (importe diretamente em vez de passar por arquivos barrel, faça code-split de componentes pesados com next/dynamic), depois evite re-renderizações desnecessárias (derive valores durante a renderização, não defina componentes dentro de componentes, eleve valores estáticos, use inicializadores de estado preguiçosos, buscas em Map, listeners de scroll passivos)."
| Tarefa | Pontuação do controle | Uma frase | Com a skill | Tokens do controle | Tokens de uma frase | Tokens com a skill | Skill lida |
|---|---|---|---|---|---|---|---|
| t1-review | 3.91 | 4.64 | 4.64 | 65k | 45k | 75k | 2/2 |
| t2-optimize | 2.27 | 4.55 | 3.64 | 90k | 130k | 163k | 2/2 |
| t3-write | 4.54 | 5.0 | 5.0 | 45k | 53k | 69k | 2/2 |
Pontuação média: 3.57 sem a skill vs. 4.43 com a skill (delta +0.85). Tokens por execução: 67k vs. 103k (1.53x); tempo 47s vs. 52s. Grupo de uma frase: 4.73 (ganho da skill sobre a frase única: -0.3; ganho da própria frase única sobre sem skill: +1.15); 77k tokens por execução no grupo de uma frase, então a skill custa 1.34x a frase única.
O que aconteceu
- Otimizar no próprio local é onde isso aparece: pontuação 2.27 controle, 3.64 skill, 4.55 versão de uma frase (as duas execuções de cada grupo idênticas). Controle e skill deixaram o barrel import
from '@/components'e não fizeram code-splitting; o controle também deixou os awaits sequenciais e o listener de scroll não passivo. A skill corrigiu a cascata e o listener de scroll, mas não o barrel import nem o import dinâmico do editor pesado; a frase única, que nomeia exatamente essas regras, corrigiu os dois. - Tarefa de análise: problemas plantados encontrados: 9 e 7 no controle (média 8), contra 10 e 10 na skill e na frase única (10 de 11 em cada; o
orders.length &&renderizando um 0 foi perdido por todas as execuções de todos os grupos). Pontuação 3.91 controle, 4.64 skill, 4.64 frase única. - Tarefa de escrita: todos os grupos colocaram as recomendações lentas atrás de Suspense e mantiveram a página como componente de servidor; o controle às vezes esperou as três chamadas em sequência (pontuação 4.1 e 5.0, skill 5.0 nas duas, frase única 5.0 nas duas).
- Nenhum grupo corrigiu
orders.length &&ao editar o arquivo, então uma regra que está na skill (rendering-conditional-render) não entrou em nenhuma edição. - A skill foi lida em 6/6 execuções e custou 103k tokens contra 67k (1.5x) e 77k da frase única (1.3x). Média geral 3.57 controle, 4.43 skill, 4.73 frase única.
- A pontuação foi corrigida uma vez durante a análise: a primeira passagem marcou erradamente as verificações de página e de Map como perdas porque o arquivo foi escrito em app/dashboard/page.tsx e o Map era tipado (
new Map<string, string>()); ambos os regexes foram corrigidos e as 18 execuções foram rechecadas.
Pontuação por dimensão
| Dimensão | Pontuação | Por quê |
|---|---|---|
| 1_output_quality | 4.43 | Pontuação média de 4.43/5 com a skill (verificações programáticas; consulte a tabela por tarefa). |
| 2_lift_vs_no_skill | 2.85 | +0.85 ponto vs. 3.57 sem a skill (n=2 por tarefa; abaixo de ~1 ponto é ruído). |
| 3_trigger | 5.0 | Arquivo da skill lido em 6/6 execuções com a skill. |
| 4_instructions_portability | 4 | Específica de React/Next.js; Markdown simples que outros agentes podem carregar; segue o layout aberto de skills. |
| 5_efficiency | 3 | 1.53x tokens (103k vs. 67k por execução) e 1.10x tempo (52s vs. 47s). |
| 6_safety_hygiene | 5 | Somente arquivos Markdown de regras; 6 achados do scanner são
|
Limites deste teste
- Fixtures pequenos com problemas clássicos conhecidos; apenas um componente foi otimizado, então duas execuções por grupo mostram o mesmo resultado pelo mesmo motivo (duas execuções idênticas).
- As 70 regras da skill foram exercitadas apenas em três tarefas; cache no servidor, SWR, listeners de eventos e regras avançadas não foram plantados.
- A versão de uma frase lista as mesmas regras que o teste verifica, então é um limite superior para um prompt curto, não um substituto justo para um usuário que não conhece as regras.
- n = 2 por grupo por tarefa: diferenças abaixo de cerca de 1 ponto são ruído.
- A pontuação por regras mede o que as verificações conseguem ver; não julga bom gosto nem se o resultado é o melhor possível.
Segurança
Consulte security.md. Scan: 6 CRITICAL / 0 HIGH / 0 MEDIUM. Veredicto: segura para execução (sandbox sem rede). Um scan limpo não prova que uma skill é segura.
Conclusão
A skill melhora claramente uma análise de desempenho e uma otimização no local em comparação com não fazer nada, que é o objetivo dela. Um prompt curto que nomeia as mesmas regras saiu melhor na tarefa de otimização e custou menos, então o valor está principalmente em conhecer os nomes das regras; os arquivos de regras da skill pouparam o usuário de precisar conhecê-las, mas não chegaram às regras de barrel import e code-splitting nestas execuções.
Transcrição
Log de execuções: vercel-react-best-practices (Codex CLI, network off, per-run temp HOME/TMPDIR, one row per graded run.) Colunas: tarefa, grupo-execução, nota (0-5), tokens, segundos, verificações aprovadas, arquivos da skill abertos pelo agente. t1-review control-1: nota 4.27, tokens 65319, s 49.8, verificações 2/2, nada aberto t1-review control-2: nota 3.55, tokens 65797, s 42.7, verificações 2/2, nada aberto t1-review oneliner-1: nota 4.64, tokens 45347, s 43.5, verificações 2/2, nada aberto t1-review oneliner-2: nota 4.64, tokens 45242, s 52.5, verificações 2/2, nada aberto t1-review treatment-1: nota 4.64, tokens 75664, s 52.7, verificações 2/2, abriu react-best-practices t1-review treatment-2: nota 4.64, tokens 75106, s 52.1, verificações 2/2, abriu react-best-practices t2-optimize control-1: nota 2.27, tokens 81770, s 63.5, verificações 5/10, nada aberto t2-optimize control-2: nota 2.27, tokens 99616, s 48.7, verificações 5/10, nada aberto t2-optimize oneliner-1: nota 4.55, tokens 141803, s 75.2, verificações 9/10, nada aberto
18 execuções, 3 artefatos
Resultado de exemplo
SOTA · With the skill: final message (t1-review, run 1, Codex)
Ranked by likely impact; no files changed. 1. **`OrdersDashboard.tsx:16` — Storage access breaks server rendering and repeats on every render.** `localStorage` is unavailable during Next.js prerendering; `'use client'` doesn’t prevent that. Initialize settings with a stable default, then read and safely parse storage once after mounting. A lazy initializer alone won’t fix server access. [Next.js rendering guidance](https://nextjs.org/docs/app/getting-started/server-and-client-components) 2. **`page.tsx:8–11` — Independent server requests run sequentially.** After `getUser`, start settings, invoices, and notifications together using `Promise.all()`. Their latency currently adds up unnecessarily. 3. **`OrdersDashboard.tsx:19–28` — Initial data waits for hydration, then follows a request waterfall.** Fetch initial data in a server parent where practical. Otherwise, after fetching `me`, request orders and customers concurrently with `Promise.all()`. Neither depends on the other. 4. **`OrdersDashboard.tsx:45–47` — Every dashboard render remounts every row.** Defining `Row` inside the component creates a new component type each render, including during scrolling and typing. Move it to module scope; consider `React.memo` with stable props. 5. **`OrdersDashboard.tsx:17,34–38,55` — Scrolling rerenders the entire dashboard.** Each scroll update repeats filtering, sorting, joins, and rendering. Move scroll state into a small standalone indicator component; throttle updates if exact continuous tracking isn’t necessary. 6. **`OrdersDashboard.tsx:7,54` — The markdown preview is eagerly loaded even for an empty footer.** Use `next/dynamic` for the preview and render it only when footer content exists. Defer mounting until needed if it is below the fold. 7. **`OrdersDashboard.tsx:40–43` — Repeated expensive calculations and quadratic customer lookups.** Memoize derived results, build a customer-ID `Map` when customers change, and parse dates once before sorting instead of inside every comparison. The join then costs O(orders + customers), rather than O(orders × customers). 8. **`OrdersDashboard.tsx:15,30–32` — Derived state causes an extra render per search/data change.** Remove `filtered` state and its effect; derive it with `useMemo`. For large datasets, use `useDeferredValue(query)` with memoized results to keep typing responsive. 9. **`page.tsx:9–15` — All sections wait for the slowest request.** Start requests together, then await them inside separate async sections under `Suspense`. This allows the sidebar to appear without waiting for feed data; wrapping JSX after all awaits won’t help. 10. **`OrdersDashboard.tsx:53` — Every matching row is mounted.** For large order collections, paginate or virtualize the table. Prefer server pagination/filtering when fetching the entire collection also becomes expensive. 11. **`OrdersDashboard.tsx:3–6` — Import cleanup and a potential barrel-import cost.** Remove unused lodash, icons, `Modal`, and `isAfter`; import used local components directly rather than through `@/components`. Confirm bundle impact before claiming unused imports ship to clients. Named `date-fns` and `lucide-react` imports already rece [... excerpt: first 3200 of 3335 characters]