🏮 Google Lighthouse 12 — Auditoría Integral de Calidad Web & Core Web Vitals

Motor Automatizado de Auditoría de Rendimiento, Accesibilidad, SEO y Buenas Prácticas

Google Lighthouse es la herramienta oficial de código abierto de Google diseñada para auditar páginas web en un entorno de laboratorio controlado (Lab Data). Evalúa el rendimiento de carga, la accesibilidad (A11Y), las mejores prácticas de seguridad moderna y el posicionamiento técnico (SEO), generando reportes accionables en formatos HTML, JSON y CLI.


🧭 Arquitectura de las 4 Categorías y Modos de Ejecución

Lighthouse 12 estructura sus auditorías en 4 categorías principales (tras el retiro del badge antiguo de PWA) y ofrece 3 modos de captura según el flujo de usuario que se desee medir:

flowchart TD
    LH(["🏮 Google Lighthouse 12"]) --> Modes["🎛️ 3 Modos de Captura"]
    LH --> Cats["📊 4 Categorías de Puntuación (0-100)"]
    
    Modes --> M1["1. Navigation (Default)\nRecarga la página desde cero y mide el cold load"]
    Modes --> M2["2. Timespan\nMide interacciones en vivo, scroll y transiciones (INP/TBT)"]
    Modes --> M3["3. Snapshot\nAnaliza el DOM y Accessibility Tree en su estado exacto actual"]
    
    Cats --> C1["⚡ Performance\n(LCP, TBT, CLS, FCP, SI)"]
    Cats --> C2["♿ Accessibility\n(Motor axe-core + reglas visuales)"]
    Cats --> C3["🛡️ Best Practices\n(HTTPS, CSP, consola limpia, mapas de fuente)"]
    Cats --> C4["🔍 SEO Técnico\n(Meta tags, robots.txt, canonical, tap targets)"]

📊 Pesos de Puntuación de Rendimiento (Lighthouse 12)

La nota de Performance (0 a 100) no es un promedio simple, sino una media ponderada calculada mediante curvas log-normales sobre 5 métricas de laboratorio:

MétricaNombre CompletoPeso (%)Umbral Verde (Óptimo)Umbral Rojo (Crítico)Qué Mide Exactamente
TBTTotal Blocking Time30%Tiempo total en que el hilo principal (Main Thread) estuvo bloqueado por tareas largas () entre FCP y TTI. Es el proxy de laboratorio para INP.
LCPLargest Contentful Paint25%Tiempo hasta que se renderiza el elemento visual más grande del viewport (imagen Hero, video o bloque H1).
CLSCumulative Layout Shift25%Estabilidad visual; cuantifica saltos inesperados de diseño provocados por imágenes sin dimensiones, fuentes web o anuncios tardíos.
FCPFirst Contentful Paint10%Tiempo desde el inicio de la navegación hasta que el navegador pinta el primer píxel de texto o imagen del DOM.
SISpeed Index10%Velocidad con la que se puebla visualmente el contenido visible durante la carga inicial (análisis cuadro por cuadro).

🌍 Datos de Laboratorio (Lighthouse) vs. Datos de Campo (Core Web Vitals / CrUX)

Diferencia Clave entre tener 100/100 en Lighthouse y Aprobar Core Web Vitals

  • Lighthouse (Lab Data): Simula la carga en un entorno controlado con estrangulamiento sintético de red y CPU (por defecto, emulando un Moto G Power sobre 4G lento). No hace clic en botones por sí solo en modo Navigation.
  • Core Web Vitals (Field Data / CrUX): Recopila telemetría real de usuarios de Chrome durante 28 días en el percentil 75 (). Evalúa las 3 métricas oficiales de posicionamiento en Google:
    1. LCP (Carga):
    2. INP — Interaction to Next Paint (Interactividad real): (reemplazó oficialmente a FID en marzo de 2024; mide la latencia de todas las interacciones de clic, toque y teclado durante toda la vida de la sesión).
    3. CLS (Estabilidad visual):

💻 Uso Avanzado desde Terminal (Lighthouse CLI)

Ejecución por Consola y Extracción Rápida de Fallos con Node/jq

# 1. Instalar o ejecutar directamente con npx / bunx
npx lighthouse https://mise-curso.pages.dev \
  --output=html,json \
  --output-path=./lh-report \
  --preset=desktop \
  --chrome-flags="--headless=new --no-sandbox"
 
# 2. Auditar únicamente Accesibilidad y Best Practices en modo móvil
npx lighthouse http://localhost:4321 \
  --only-categories=accessibility,best-practices \
  --output=json \
  --output-path=./a11y-report.json \
  --quiet
 
# 3. One-liner para filtrar únicamente las auditorías que fallaron (< 100%)
node -e "const r=require('./a11y-report.json'); Object.values(r.audits).filter(a=>a.score!==null && a.score<1).forEach(a=>console.log(JSON.stringify({id:a.id, title:a.title, score:a.score, items:a.details?.items?.length})))"

🤖 Automatización con Lighthouse CI (LHCI) en GitHub Actions

Para impedir que un Pull Request degrade el rendimiento o la accesibilidad antes de llegar a producción, se configura Lighthouse CI:

1. Archivo de Presupuesto de Calidad (lighthouserc.json)

{
  "ci": {
    "collect": {
      "startServerCommand": "pnpm preview",
      "url": [
        "http://localhost:4321/",
        "http://localhost:4321/cursos"
      ],
      "numberOfRuns": 3
    },
    "assert": {
      "preset": "lighthouse:recommended",
      "assertions": {
        "categories:performance": ["error", { "minScore": 0.95 }],
        "categories:accessibility": ["error", { "minScore": 1.0 }],
        "categories:best-practices": ["error", { "minScore": 0.95 }],
        "categories:seo": ["error", { "minScore": 0.95 }],
        "largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
        "total-blocking-time": ["error", { "maxNumericValue": 200 }],
        "cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }]
      }
    },
    "upload": {
      "target": "temporary-public-storage"
    }
  }
}

2. Workflow de GitHub Actions (.github/workflows/lighthouse.yml)

name: 🏮 Lighthouse CI Quality Gate
 
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
 
jobs:
  lhci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        with:
          version: 9
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'pnpm'
 
      - name: Instalar y Compilar Proyecto
        run: |
          pnpm install --frozen-lockfile
          pnpm build
 
      - name: Ejecutar Auditoría Lighthouse CI
        uses: treosh/lighthouse-ci-action@v12
        with:
          configPath: './lighthouserc.json'
          uploadArtifacts: true
          temporaryPublicStorage: true

🚀 Playbook Táctico para Alcanzar el 100 / 100 / 100 / 100

Guía de Optimización por Categoría

  1. Optimizar LCP ():
    • En la imagen Hero principal, usar siempre fetchpriority="high" y loading="eager" (nunca uses loading="lazy" en la imagen principal sobre el pliegue).
    • Servir formatos de nueva generación (AVIF o WebP) con tamaños responsivos srcset.
    • Preconectar orígenes críticos (<link rel="preconnect" href="...">).
  2. Eliminar CLS ():
    • Declarar atributos explícitos width y height (o aspect-ratio en CSS) en todas las etiquetas <img>, <video> e <iframe>.
    • Usar font-display: swap u optional junto con métricas de fuente ajustadas (size-adjust) para evitar parpadeos al cargar tipografías.
  3. Reducir TBT e INP ():
    • Adoptar arquitecturas de Cero JS por defecto como Astro (Server Islands / Hidratación Parcial con client:visible o client:idle).
    • Particionar tareas largas de JavaScript cediendo el hilo principal con scheduler.yield() o requestIdleCallback.
  4. Blindar Best Practices (100/100):
    • Configurar correctamente los Headers de Seguridad HTTP (CSP, HSTS, COOP) y eliminar cualquier error en consola o APIs deprecadas.

🔗 Conexiones en la Bóveda