Desarrollo Web #Rendimiento Web #Core Web Vitals #Lighthouse #SEO #Optimización #Desarrollo Web #Freelance #Valencia

Optimización rendimiento web freelance Valencia: Core Web Vitals, LCP, FID, CLS guía completa 2025

Optimización rendimiento web freelance Valencia: mejora Core Web Vitals, LCP, FID, CLS para alcanzar 100/100 Lighthouse. Técnicas prácticas desarrollo web España 2025.

18 min de lectura
Optimización rendimiento web freelance Valencia: Core Web Vitals, LCP, FID, CLS guía completa 2025

Optimización rendimiento web freelance Valencia: Core Web Vitals, LCP, FID, CLS guía completa 2025

Introducción: La velocidad es el nuevo SEO

En 2025, Google penaliza los sitios lentos. No es opcional: es obligatorio.

Como desarrollador freelance, he optimizado docenas de sitios. He visto cómo un sitio que carga en 1 segundo convierte 3x más que uno que carga en 5 segundos.

En este artículo te doy mi guía completa de optimización: técnicas probadas, herramientas y casos reales que han mejorado el rendimiento de mis clientes en 200-300%.

Los Core Web Vitals: Las métricas que importan

1. LCP (Largest Contentful Paint) - Contenido principal

¿Qué mide? Cuándo aparece el contenido más grande visible.

Objetivo: <2.5 segundos

Cómo mejorar LCP

Problema común: Imágenes no optimizadas

<!-- ❌ Antes: Imagen sin optimizar -->
<img src="hero-image.jpg" alt="Hero" style="width: 100%; height: 400px;">
<!-- ✅ Después: Imagen optimizada -->
<img
  src="hero-image.webp"
  alt="Hero"
  width="1200"
  height="400"
  loading="eager"
  decoding="async"
  style="width: 100%; height: auto;"
>

Técnicas avanzadas para LCP:

// Preload recursos críticos
<link rel="preload" href="/hero-image.webp" as="image" type="image/webp">
<link rel="preload" href="/hero-font.woff2" as="font" type="font/woff2" crossorigin>

// Critical CSS inline
<style>
  .hero { background: #fff; font-family: 'Inter'; }
  .hero h1 { font-size: 3rem; color: #000; }
</style>

2. FID (First Input Delay) - Interactividad

¿Qué mide? Retraso en respuesta a la primera interacción.

Objetivo: <100 milisegundos

Causas comunes de FID malo

  1. JavaScript bloqueante
  2. Tareas largas del main thread
  3. No dividir código (code splitting)
// ❌ Código bloqueante
import { heavyLibrary } from 'heavy-lib'; // Se carga todo al inicio
import { unusedComponent } from './components'; // Nunca se usa

// ✅ Code splitting inteligente
const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  const [showHeavy, setShowHeavy] = useState(false);

  return (
    <div>
      <button onClick={() => setShowHeavy(true)}>
        Load heavy component
      </button>
      {showHeavy && <HeavyComponent />}
    </div>
  );
}

3. CLS (Cumulative Layout Shift) - Estabilidad visual

¿Qué mide? Cambios inesperados en el layout.

Objetivo: <0.1

Cómo eliminar CLS

/* ❌ Dimensiones no especificadas */
<img src="image.jpg" alt="Image">

/* ✅ Dimensiones explícitas */
img {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
}

/* O usando CSS moderno */
.image-container {
  aspect-ratio: 16 / 9;
  background: #f0f0f0;
}

Prevención de CLS en fuentes:

/* Evitar FOIT (Flash of Invisible Text) */
@font-face {
  font-family: 'Inter';
  font-display: swap; /* Muestra fallback inmediatamente */
  src: url('/fonts/inter.woff2') format('woff2');
}

Stack de optimización: Herramientas que uso

1. Next.js + Vercel (Mi combo favorito)

// next.config.js - Configuración optimizada
/** @type {import('next').NextConfig} */
const nextConfig = {
  // Imágenes automáticas optimizadas
  images: {
    formats: ['image/webp', 'image/avif'],
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
  },

  // Compresión automática
  compress: true,

  // Bundle analyzer
  webpack: (config, { dev }) => {
    if (!dev) {
      config.optimization.splitChunks.chunks = 'all';
    }
    return config;
  },

  // Headers de cache
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          { key: 'X-Frame-Options', value: 'DENY' },
          { key: 'X-Content-Type-Options', value: 'nosniff' },
        ],
      },
      {
        source: '/static/(.*)',
        headers: [
          { key: 'Cache-Control', value: 'public, max-age=31536000, immutable' },
        ],
      },
    ];
  },
};

module.exports = nextConfig;

2. Astro: Rendimiento por defecto

// astro.config.mjs
import { defineConfig } from 'astro/config';
import image from '@astrojs/image';
import compress from 'astro-compress';

export default defineConfig({
  site: 'https://tu-sitio.com',
  integrations: [
    image({
      serviceEntryPoint: '@astrojs/image/sharp',
    }),
    compress(),
  ],

  // Optimizaciones automáticas
  vite: {
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            vendor: ['astro'],
          },
        },
      },
    },
  },
});

3. CDN y Edge Computing

// vercel.json - Configuración edge
{
  "functions": {
    "api/**/*.js": {
      "runtime": "@vercel/node"
    }
  },
  "rewrites": [
    {
      "source": "/api/(.*)",
      "destination": "/api/$1"
    }
  ],
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    }
  ]
}

Técnicas avanzadas de optimización

1. Resource Hints: Cargar lo que necesitas antes

<!-- Preload recursos críticos -->
<link rel="preload" href="/css/critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<link rel="preload" href="/js/main.js" as="script">

<!-- Preconnect a dominios externos -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- DNS prefetch para recursos no críticos -->
<link rel="dns-prefetch" href="//cdn.example.com">

2. Critical CSS: CSS que importa primero

// Extraer CSS crítico automáticamente
import critical from 'critical';

await critical.generate({
  inline: true,
  base: 'dist/',
  src: 'index.html',
  target: 'index.html',
  width: 1300,
  height: 900,
});

3. Service Worker para cache avanzado

// sw.js - Service Worker para cache
const CACHE_NAME = 'v1';
const urlsToCache = [
  '/',
  '/css/styles.css',
  '/js/main.js',
  '/images/logo.webp',
];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then((cache) => cache.addAll(urlsToCache))
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => {
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

4. Optimización de fuentes web

/* Sistema de fuentes optimizado */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-regular.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Font loading strategy */
.font-loading {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

5. Lazy loading inteligente

// Intersection Observer para lazy loading
const images = document.querySelectorAll('img[data-src]');

const imageObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target as HTMLImageElement;
      img.src = img.dataset.src!;
      img.classList.remove('lazy');
      observer.unobserve(img);
    }
  });
});

images.forEach(img => imageObserver.observe(img));

Casos reales: Optimizaciones que funcionaron

Caso 1: E-commerce B2B - De 8s a 1.2s

Cliente: Plataforma de pedidos mayoristas

Problemas iniciales:

  • LCP: 6.8s
  • FID: 450ms
  • CLS: 0.35
  • Lighthouse: 45/100

Soluciones implementadas:

  1. Imágenes optimizadas: WebP + lazy loading
  2. Code splitting: Componentes críticos separados
  3. CDN global: Assets servidos desde edge
  4. Database optimization: Queries optimizadas

Resultados:

  • ⏱️ LCP: 1.2s (-82%)
  • FID: 45ms (-90%)
  • 📏 CLS: 0.05 (-86%)
  • 📊 Lighthouse: 95/100 (+110%)
  • 💰 Conversion rate: +65%

Caso 2: Blog corporativo - De 4.5s a 0.8s

Cliente: Blog de empresa tecnológica

Problemas iniciales:

  • Múltiples plugins WordPress lentos
  • Imágenes sin optimizar
  • CSS/JS no minificado
  • Sin cache adecuado

Migración a headless:

  • WordPress → CMS headless
  • Next.js + SSG
  • Imágenes automáticas optimizadas
  • Critical CSS inline

Resultados:

  • ⏱️ Carga inicial: 0.8s (-82%)
  • 📈 SEO: Posición 1 en keywords principales
  • 👥 Tráfico orgánico: +180%
  • 💰 ROI: Recuperado en 3 meses

Caso 3: App React - De 12s a 2.1s

Cliente: Dashboard de analytics

Problemas iniciales:

  • Bundle de 8MB
  • Sin code splitting
  • Librerías pesadas innecesarias
  • Re-renders excesivos

Optimizaciones:

  1. Tree shaking: Eliminar código muerto
  2. Dynamic imports: Componentes bajo demanda
  3. Memoización: React.memo + useMemo
  4. Virtualización: React Window para listas grandes

Resultados:

  • 📦 Bundle size: 2.1MB (-74%)
  • First paint: 1.1s (-91%)
  • 🔄 Interactions: Fluido 60fps
  • 😊 UX Score: +300%

Herramientas de medición y monitoreo

Lighthouse CI en GitHub Actions

# .github/workflows/lighthouse.yml
name: Lighthouse CI
on: [push, pull_request]

jobs:
  lighthouse:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '18'

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Serve and test
        run: |
          npx serve dist -l 3000 &
          sleep 3
          npx lighthouse http://localhost:3000 \
            --output=json \
            --output-path=./lighthouse-results.json \
            --chrome-flags="--headless --disable-gpu"

      - name: Comment PR
        uses: dorny/test-reporter@v1
        with:
          name: Lighthouse Results
          path: 'lighthouse-results.json'
          reporter: 'lighthouse-json'

Web Vitals monitoring en producción

// lib/web-vitals.ts
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';

export function reportWebVitals(metric) {
  // Enviar a analytics
  if (typeof window !== 'undefined' && window.gtag) {
    window.gtag('event', metric.name, {
      value: Math.round(metric.value),
      event_category: 'Web Vitals',
      event_label: metric.id,
      non_interaction: true,
    });
  }

  // Console log en desarrollo
  if (process.env.NODE_ENV === 'development') {
    console.log(metric);
  }
}

// Inicializar medición
if (typeof window !== 'undefined') {
  getCLS(reportWebVitals);
  getFID(reportWebVitals);
  getFCP(reportWebVitals);
  getLCP(reportWebVitals);
  getTTFB(reportWebVitals);
}

Real User Monitoring (RUM)

// Monitoring con Sentry
import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 1.0,
  integrations: [
    new Sentry.BrowserTracing({
      routingInstrumentation: Sentry.nextRouterInstrumentation,
    }),
  ],
  // Performance monitoring
  enableTracing: true,
});

Checklist de optimización: 30 días para 100/100

Semana 1: Fundamentos

  • Auditar sitio actual con Lighthouse
  • Implementar compresión (gzip/brotli)
  • Optimizar imágenes (WebP, responsive)
  • Minificar CSS/JS
  • Configurar cache headers

Semana 2: Core Web Vitals

  • Mejorar LCP (<2.5s)
  • Optimizar FID (<100ms)
  • Eliminar CLS (<0.1)
  • Critical CSS inline
  • Resource hints (preload, preconnect)

Semana 3: Avanzado

  • Code splitting
  • Lazy loading
  • CDN implementation
  • Service Worker cache
  • Database optimization

Semana 4: Monitoreo

  • Lighthouse CI setup
  • Web Vitals tracking
  • Real User Monitoring
  • Alertas de performance
  • Reportes automáticos

Conclusión: Rendimiento como ventaja competitiva

Los sitios lentos pierden clientes. Los rápidos los ganan.

En 2025, el rendimiento no es técnico: es negocio. Cada segundo cuenta.

¿Necesitas optimizar tu sitio web? Contáctame y alcancemos juntos ese 100/100 en Lighthouse.


Preguntas frecuentes (FAQ)

¿Cuál es el objetivo de LCP/FID/CLS para 2025?
LCP < 2.5s, FID < 100ms (o INP < 200ms) y CLS < 0.1. Apunta a 100/100 en Lighthouse en páginas clave.

¿Qué impacto tiene en SEO?
Core Web Vitals son señal de ranking. Mejorar rendimiento suele aumentar conversiones y posicionamiento.

¿Qué optimizaciones dan mayor impacto rápido?
Imágenes WebP/AVIF + lazyload, critical CSS, preload de fuentes, code splitting y cache/CDN.

¿Cómo monitorizo en producción?
Web Vitals + Google Analytics (gtag) y, si puedes, RUM o Sentry Performance para métricas reales de usuarios.


Recursos relacionados


Publicado el 17 de diciembre de 2025 por Adrián Pozo Esteban - Desarrollador Full Stack Freelance especializado en optimización de rendimiento web y Core Web Vitals en Valencia, España

Compartir este artículo

Artículos Relacionados