본문으로 건너뛰기
cccskills
무료GitHub에 공개

core-web-vitals

Otimize Core Web Vitals (LCP, INP, CLS) para melhor experiência de página e ranking de busca. Use quando solicitado para "melhorar Core Web Vitals", "corrigir LCP", "reduzir CLS", "otimizar INP", "otimização de experiência de página" ou "corrigir deslocamentos de layout".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(2)

  • SKILL.md12.2 KB
  • references/LCP.md4.3 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Otimização de Core Web Vitals

Otimização direcionada para as três métricas de Core Web Vitals que afetam o ranking do Google Search e a experiência do usuário.

As três métricas

MétricaMedeBomPrecisa melhorarRuim
LCPCarregamento≤ 2,5s2,5s – 4s> 4s
INPInteratividade≤ 200ms200ms – 500ms> 500ms
CLSEstabilidade visual≤ 0,10,1 – 0,25> 0,25

O Google mede no 75º percentil — 75% das visitas de página devem atender aos limites "Bom".


LCP: Largest Contentful Paint

LCP mede quando o maior elemento de conteúdo visível é renderizado. Geralmente é:

  • Imagem ou vídeo em destaque
  • Bloco de texto grande
  • Imagem de fundo
  • Elemento <svg>

Problemas comuns de LCP

1. Resposta lenta do servidor (TTFB > 800ms)

Solução: CDN, cache, backend otimizado, renderização em edge

2. Recursos que bloqueiam renderização

<!-- ❌ Bloqueia renderização -->
<link rel="stylesheet" href="/all-styles.css">

<!-- ✅ CSS crítico incorporado, restante adiado -->
<style>/* CSS crítico acima da dobra */</style>
<link rel="preload" href="/styles.css" as="style" 
      onload="this.onload=null;this.rel='stylesheet'">

3. Tempo lento de carregamento de recursos

<!-- ❌ Sem dicas, descoberto tarde -->
<img src="/hero.jpg" alt="Hero">

<!-- ✅ Pré-carregado com alta prioridade -->
<link rel="preload" href="/hero.webp" as="image" fetchpriority="high">
<img src="/hero.webp" alt="Hero" fetchpriority="high">

4. Atrasos na renderização no cliente

// ❌ Conteúdo carrega após JavaScript
useEffect(() => {
  fetch('/api/hero-text').then(r => r.json()).then(setHeroText);
}, []);

// ✅ Renderização no servidor ou estática
// Use SSR, SSG ou streaming para enviar HTML com conteúdo
export async function getServerSideProps() {
  const heroText = await fetchHeroText();
  return { props: { heroText } };
}

Checklist de otimização de LCP

- [ ] TTFB < 800ms (use CDN, cache em edge)
- [ ] Imagem LCP pré-carregada com fetchpriority="high"
- [ ] Imagem LCP otimizada (WebP/AVIF, tamanho correto)
- [ ] CSS crítico incorporado (< 14KB)
- [ ] Nenhum JavaScript que bloqueie renderização em <head>
- [ ] Fontes não bloqueiam renderização de texto (font-display: swap)
- [ ] Elemento LCP no HTML inicial (não renderizado por JS)

Identificação do elemento LCP

// Encontre seu elemento LCP
new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];
  console.log('LCP element:', lastEntry.element);
  console.log('LCP time:', lastEntry.startTime);
}).observe({ type: 'largest-contentful-paint', buffered: true });

INP: Interaction to Next Paint

INP mede a responsividade em TODAS as interações (cliques, toques, pressionamento de teclas) durante uma visita à página. Ele relata a pior interação (no 98º percentil para páginas de alto tráfego).

Decomposição de INP

Total INP = Input Delay + Processing Time + Presentation Delay

FaseAlvoOtimização
Input Delay< 50msReduza bloqueio da thread principal
Processing< 100msOtimize manipuladores de eventos
Presentation< 50msMinimize trabalho de renderização

Problemas comuns de INP

1. Tarefas longas bloqueando a thread principal

// ❌ Tarefa síncrona longa
function processLargeArray(items) {
  items.forEach(item => expensiveOperation(item));
}

// ✅ Divida em chunks com yielding
async function processLargeArray(items) {
  const CHUNK_SIZE = 100;
  for (let i = 0; i < items.length; i += CHUNK_SIZE) {
    const chunk = items.slice(i, i + CHUNK_SIZE);
    chunk.forEach(item => expensiveOperation(item));
    
    // Ceda à thread principal
    await new Promise(r => setTimeout(r, 0));
    // Ou use scheduler.yield() quando disponível
  }
}

2. Manipuladores de eventos pesados

// ❌ Todo trabalho no manipulador
button.addEventListener('click', () => {
  // Computação pesada
  const result = calculateComplexThing();
  // Atualizações de DOM
  updateUI(result);
  // Analytics
  trackEvent('click');
});

// ✅ Priorize feedback visual imediato
button.addEventListener('click', () => {
  // Feedback visual imediato
  button.classList.add('loading');
  
  // Adie trabalho não-crítico
  requestAnimationFrame(() => {
    const result = calculateComplexThing();
    updateUI(result);
  });
  
  // Use requestIdleCallback para analytics
  requestIdleCallback(() => trackEvent('click'));
});

3. Scripts de terceiros

// ❌ Carregado com entusiasmo, bloqueia interações
<script src="https://heavy-widget.com/widget.js"></script>

// ✅ Carregado com preguiça na interação ou visibilidade
const loadWidget = () => {
  import('https://heavy-widget.com/widget.js')
    .then(widget => widget.init());
};
button.addEventListener('click', loadWidget, { once: true });

4. Re-renderizações excessivas (React/Vue)

// ❌ Re-renderiza toda a árvore
function App() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <Counter count={count} />
      <ExpensiveComponent /> {/* Re-renderiza a cada mudança de count */}
    </div>
  );
}

// ✅ Componentes caros memoizados
const MemoizedExpensive = React.memo(ExpensiveComponent);

function App() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <Counter count={count} />
      <MemoizedExpensive />
    </div>
  );
}

Checklist de otimização de INP

- [ ] Nenhuma tarefa > 50ms na thread principal
- [ ] Manipuladores de eventos concluem rapidamente (< 100ms)
- [ ] Feedback visual fornecido imediatamente
- [ ] Trabalho pesado adiado com requestIdleCallback
- [ ] Scripts de terceiros não bloqueiam interações
- [ ] Manipuladores de entrada com debounce quando apropriado
- [ ] Web Workers para operações intensivas de CPU

Depuração de INP

// Identifique interações lentas
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.duration > 200) {
      console.warn('Slow interaction:', {
        type: entry.name,
        duration: entry.duration,
        processingStart: entry.processingStart,
        processingEnd: entry.processingEnd,
        target: entry.target
      });
    }
  }
}).observe({ type: 'event', buffered: true, durationThreshold: 16 });

CLS: Cumulative Layout Shift

CLS mede deslocamentos de layout inesperados. Um deslocamento ocorre quando um elemento visível muda de posição entre quadros sem interação do usuário.

Fórmula de CLS: impacto de fração × fração de distância

Causas comuns de CLS

1. Imagens sem dimensões

<!-- ❌ Causa deslocamento de layout quando carregada -->
<img src="photo.jpg" alt="Photo">

<!-- ✅ Espaço reservado -->
<img src="photo.jpg" alt="Photo" width="800" height="600">

<!-- ✅ Ou use aspect-ratio -->
<img src="photo.jpg" alt="Photo" style="aspect-ratio: 4/3; width: 100%;">

2. Anúncios, embeds e iframes

<!-- ❌ Tamanho desconhecido até carregar -->
<iframe src="https://ad-network.com/ad"></iframe>

<!-- ✅ Reserve espaço com min-height -->
<div style="min-height: 250px;">
  <iframe src="https://ad-network.com/ad" height="250"></iframe>
</div>

<!-- ✅ Ou use container com aspect-ratio -->
<div style="aspect-ratio: 16/9;">
  <iframe src="https://youtube.com/embed/..." 
          style="width: 100%; height: 100%;"></iframe>
</div>

3. Conteúdo injetado dinamicamente

// ❌ Insere conteúdo acima do viewport
notifications.prepend(newNotification);

// ✅ Insira abaixo do viewport ou use transform
const insertBelow = viewport.bottom < newNotification.top;
if (insertBelow) {
  notifications.prepend(newNotification);
} else {
  // Anime sem deslocar
  newNotification.style.transform = 'translateY(-100%)';
  notifications.prepend(newNotification);
  requestAnimationFrame(() => {
    newNotification.style.transform = '';
  });
}

4. Fontes web causando FOUT

/* ❌ Troca de fonte desloca texto */
@font-face {
  font-family: 'Custom';
  src: url('custom.woff2') format('woff2');
}

/* ✅ Fonte opcional (sem deslocamento se lenta) */
@font-face {
  font-family: 'Custom';
  src: url('custom.woff2') format('woff2');
  font-display: optional;
}

/* ✅ Ou combine métricas de fallback */
@font-face {
  font-family: 'Custom';
  src: url('custom.woff2') format('woff2');
  font-display: swap;
  size-adjust: 105%; /* Combine tamanho de fallback */
  ascent-override: 95%;
  descent-override: 20%;
}

5. Animações disparando layout

/* ❌ Anima propriedades de layout */
.animate {
  transition: height 0.3s, width 0.3s;
}

/* ✅ Use transform em vez disso */
.animate {
  transition: transform 0.3s;
}
.animate.expanded {
  transform: scale(1.2);
}

Checklist de otimização de CLS

- [ ] Todas as imagens têm width/height ou aspect-ratio
- [ ] Todos os vídeos/embeds têm espaço reservado
- [ ] Anúncios têm containers com min-height
- [ ] Fontes usam font-display: optional ou métricas combinadas
- [ ] Conteúdo dinâmico inserido abaixo do viewport
- [ ] Animações usam apenas transform/opacity
- [ ] Nenhum conteúdo injetado acima do conteúdo existente

Depuração de CLS

// Rastreie deslocamentos de layout
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) {
      console.log('Layout shift:', entry.value);
      entry.sources?.forEach(source => {
        console.log('  Shifted element:', source.node);
        console.log('  Previous rect:', source.previousRect);
        console.log('  Current rect:', source.currentRect);
      });
    }
  }
}).observe({ type: 'layout-shift', buffered: true });

Ferramentas de medição

Testes em laboratório

  • Chrome DevTools → Painel Performance, Lighthouse
  • WebPageTest → Detalhado waterfall, filmstrip
  • Lighthouse CLI → npx lighthouse <url>

Dados de campo (usuários reais)

  • Chrome User Experience Report (CrUX) → BigQuery ou API
  • Search Console → Relatório de Core Web Vitals
  • web-vitals library → Envie para sua analytics
import {onLCP, onINP, onCLS} from 'web-vitals';

function sendToAnalytics({name, value, rating}) {
  gtag('event', name, {
    event_category: 'Web Vitals',
    value: Math.round(name === 'CLS' ? value * 1000 : value),
    event_label: rating
  });
}

onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);

Correções rápidas por framework

Next.js

// LCP: Use next/image com priority
import Image from 'next/image';
<Image src="/hero.jpg" priority fill alt="Hero" />

// INP: Use importação dinâmica
const HeavyComponent = dynamic(() => import('./Heavy'), { ssr: false });

// CLS: Componente Image cuida automaticamente das dimensões

React

// LCP: Pré-carregue na head
<link rel="preload" href="/hero.jpg" as="image" fetchpriority="high" />

// INP: Memoize e useTransition
const [isPending, startTransition] = useTransition();
startTransition(() => setExpensiveState(newValue));

// CLS: Sempre especifique dimensões em tags img

Vue/Nuxt

<!-- LCP: Use nuxt/image com preload -->
<NuxtImg src="/hero.jpg" preload loading="eager" />

<!-- INP: Use componentes assíncronos -->
<component :is="() => import('./Heavy.vue')" />

<!-- CLS: Use CSS aspect-ratio -->
<img :style="{ aspectRatio: '16/9' }" />

Referências

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Especialista em construir experiências 3D para a web - Three.js, React Three Fiber, Spline, WebGL e cenas 3D interativas. Cobre configuradores de produtos, portfólios 3D, websites imersivos e adição de profundidade às experiências web. Use quando: website 3D, three.js, WebGL, react three fiber, experiência 3D.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

artubss/SKILLS-CLAUDE-CODE112026년 5월 17일 업데이트

Quando o usuário quer planejar, projetar ou implementar um teste A/B ou experimento. Também use quando o usuário menciona "teste A/B", "split test", "experimento", "testar essa mudança", "copy variante", "teste multivariado" ou "hipótese". Para implementação de rastreamento, veja analytics-tracking.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

artubss/SKILLS-CLAUDE-CODE112026년 5월 17일 업데이트

Auditar e melhorar a acessibilidade web seguindo as diretrizes WCAG 2.1. Use quando solicitado para "melhorar acessibilidade", "auditoria a11y", "conformidade WCAG", "suporte a leitor de tela", "navegação por teclado" ou "tornar acessível".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

artubss/SKILLS-CLAUDE-CODE112026년 5월 17일 업데이트

Testes e benchmarking de agentes LLM incluindo testes comportamentais, avaliação de capacidades, métricas de confiabilidade e monitoramento em produção—onde até os melhores agentes alcançam menos de 50% em benchmarks do mundo real. Use quando: testes de agentes, avaliação de agentes, benchmark de agentes, confiabilidade de agentes, teste de agentes.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

artubss/SKILLS-CLAUDE-CODE112026년 5월 17일 업데이트

Criar, gerenciar e orquestrar agentes de IA usando o CLI AI Maestro. Use quando o usuário pedir para "criar agente", "listar agentes", "deletar agente", "hibernar agente", "despertar agente", "instalar plugin", "mostrar agente", "reiniciar agente" ou qualquer tarefa de gerenciamento do ciclo de vida do agente.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

artubss/SKILLS-CLAUDE-CODE112026년 5월 17일 업데이트

Gerencie múltiplos agentes CLI locais via sessões tmux (iniciar/parar/monitorar/atribuir) com agendamento compatível com cron.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

artubss/SKILLS-CLAUDE-CODE112026년 5월 17일 업데이트

artubss의 스킬 모두 보기

이 스킬의 문제 신고