Optimiza rendimiento con code splitting y caching

Video
20 min~4 min lectura

Reproductor de video

Concepto clave

El code splitting y el caching son dos técnicas fundamentales para optimizar el rendimiento de aplicaciones web modernas. Imagina que tu aplicación es como una biblioteca gigante: sin code splitting, el usuario tendría que cargar todos los libros al entrar, aunque solo necesite leer uno. Con code splitting, solo carga los libros que necesita en ese momento, reduciendo el tiempo de espera inicial.

El caching funciona como una memoria temporal que almacena recursos ya descargados. Cuando el usuario vuelve a visitar tu aplicación, no necesita descargar todo de nuevo, similar a cómo recordamos el camino a casa sin consultar un mapa cada vez. En SvelteKit, estas técnicas se implementan de forma nativa, aprovechando la arquitectura basada en componentes y rutas.

Cómo funciona en la práctica

En SvelteKit, el code splitting ocurre automáticamente a nivel de ruta. Cada archivo +page.svelte y +page.server.js se convierte en un chunk separado que se carga solo cuando el usuario navega a esa ruta. Para optimizar aún más, puedes usar importaciones dinámicas para componentes pesados que no son críticos para la carga inicial.

El caching se gestiona a través de headers HTTP configurados en los endpoints de SvelteKit. Por ejemplo, puedes cachear recursos estáticos como imágenes o CSS por largos períodos, mientras que datos dinámicos pueden tener un cache más corto. Esto reduce las solicitudes al servidor y mejora la experiencia del usuario, especialmente en conexiones lentas.

Código en acción

Veamos un ejemplo de code splitting con importación dinámica en un componente Svelte:

// Antes: Carga todo al inicio
import HeavyChart from './HeavyChart.svelte';

export let data;

// En el template: <HeavyChart {data} />
// Después: Carga solo cuando se necesita
import { onMount } from 'svelte';

export let data;
let HeavyChart;

onMount(async () => {
  if (data.length > 0) {
    const module = await import('./HeavyChart.svelte');
    HeavyChart = module.default;
  }
});

// En el template: {#if HeavyChart} <svelte:component this={HeavyChart} {data} /> {/if}

Configuración de caching en un endpoint de SvelteKit:

// En src/routes/api/productos/+server.js
export async function GET({ url }) {
  const products = await db.products.findMany();
  
  return new Response(JSON.stringify(products), {
    headers: {
      'Content-Type': 'application/json',
      'Cache-Control': 'public, max-age=3600, stale-while-revalidate=600'
    }
  });
}

Errores comunes

  • Sobredividir el código: Crear chunks demasiado pequeños puede aumentar el número de solicitudes HTTP. Solución: Agrupa componentes relacionados lógicamente.
  • Cache demasiado agresivo: Cachear datos que cambian frecuentemente puede mostrar información obsoleta. Solución: Usa max-age apropiado y considera stale-while-revalidate.
  • Olvidar el loading state: No mostrar un indicador de carga durante importaciones dinámicas frustra al usuario. Solución: Implementa skeletons o spinners.
  • Ignorar el bundle analysis: No medir el impacto de tus optimizaciones. Solución: Usa @sveltejs/package o herramientas como Webpack Bundle Analyzer.

Checklist de dominio

  1. Identifiqué al menos 3 componentes en mi app que pueden beneficiarse de code splitting.
  2. Configuré headers de cache para recursos estáticos y endpoints API.
  3. Implementé loading states para todas las importaciones dinámicas.
  4. Analicé el bundle resultante para verificar la división efectiva.
  5. Probé la app con conexión lenta para validar mejoras.
  6. Documenté las estrategias de cache implementadas.
  7. Establecí métricas de rendimiento antes y después de las optimizaciones.

Optimiza una aplicación de dashboard con code splitting y caching

En este ejercicio, optimizarás un dashboard existente que carga todos sus componentes al inicio, causando una carga lenta.

  1. Analiza la estructura actual: Abre el proyecto y revisa el archivo src/routes/dashboard/+page.svelte. Identifica al menos 3 componentes pesados (ej: gráficos, tablas grandes) que no son críticos para la carga inicial.
  2. Implementa code splitting: Refactoriza los componentes identificados para usar importación dinámica. Asegúrate de agregar estados de carga (skeletons) mientras se cargan.
  3. Configura caching: En el endpoint src/routes/api/analytics/+server.js, agrega headers de cache apropiados. Los datos de analytics cambian cada hora, así que configura max-age=1800 y stale-while-revalidate=300.
  4. Mide el impacto: Usa las DevTools de tu navegador para comparar el tamaño del bundle inicial antes y después. Verifica que los chunks se carguen bajo demanda.
Pistas
  • Usa import() dentro de onMount para cargar componentes solo cuando el padre se monta.
  • Para los skeletons, puedes usar elementos div con estilos de placeholder mientras se carga el componente real.
  • Recuerda que stale-while-revalidate permite servir contenido cacheado mientras se actualiza en segundo plano.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.