Mejores prácticas de rendimiento web

La velocidad del sitio web no es un lujo: es una métrica empresarial fundamental. Los datos son contundentes:
Por qué es importante el rendimiento
La velocidad del sitio web no es un lujo: es una métrica empresarial fundamental. Los datos son contundentes:
- Conversiones: un retraso de 1 segundo en la carga de la página reduce las conversiones en un 7 % (Amazon estimó 1,600 millones de dólares en pérdida de ingresos anuales por cada 100 ms de latencia).
- SEO: Google utiliza Core Web Vitals como señales de clasificación desde 2021.
- Experiencia de usuario: el 53 % de los usuarios de dispositivos móviles abandonan los sitios que tardan más de 3 segundos en cargarse.
- Accesibilidad: los sitios más rápidos funcionan mejor en redes lentas y dispositivos más antiguos.
Cada milisegundo cuenta. Este artículo cubre estrategias integrales para hacer que sus sitios web sean increíblemente rápidos.
1. Optimice los activos
Minificación
Elimine espacios en blanco, comentarios y caracteres innecesarios de HTML, CSS y JavaScript. Las herramientas de compilación modernas manejan esto automáticamente:
# Using Terser for JavaScript
npx terser input.js -o output.min.js --compress --mangle
# Using cssnano via PostCSS
npx postcss input.css -o output.min.css --use cssnano
# Using html-minifier
npx html-minifier input.html -o output.min.html --collapse-whitespace
Impacto: la minificación normalmente reduce el tamaño de los archivos entre un 30% y un 60%.
Optimización de imagen
Las imágenes representan más del 50% del peso de la página en la mayoría de los sitios web.
Formatos modernos:
- WebP: entre un 25 % y un 35 % más pequeño que JPEG con la misma calidad. Compatible con todos los navegadores modernos.
- AVIF: 50% más pequeño que JPEG. Basado en el códec de vídeo AV1. Apoyo creciente.
- SVG — Formato vectorial ideal para iconos, logotipos e ilustraciones.
Imágenes responsivas:
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="Description"
loading="lazy"
/>
Herramientas:
- Sharp (Node.js): procesamiento de imágenes del lado del servidor.
- Squoosh: optimizador de imágenes basado en navegador.
- ImageOptim: compresión sin pérdidas para producción.
- Cloudinary / Imgix: optimización de imágenes en tiempo real basada en CDN.
Impacto: la optimización adecuada de la imagen puede reducir el peso de la página entre un 60 y un 80 %.
División de código y agitación de árboles
División de código divide tu JavaScript en fragmentos cargados bajo demanda:
// React lazy loading
const Dashboard = React.lazy(() => import('./Dashboard'));
// Webpack dynamic import
import(/* webpackChunkName: "chart" */ './Chart').then(module => {
module.renderChart();
});
La sacudida de árboles elimina el código muerto. Webpack, Rollup y esbuild eliminan las exportaciones no utilizadas durante la agrupación. Asegúrese de utilizar módulos ES (import/export) para que la sacudida de árboles funcione de manera efectiva.
2. Aprovechar el almacenamiento en caché
El almacenamiento en caché sirve recursos previamente obtenidos del almacenamiento local, evitando por completo las solicitudes de red.
Almacenamiento en caché del navegador (encabezados HTTP)
# Apache .htaccess
<FilesMatch "\.(ico|pdf|jpg|jpeg|png|gif|js|css|svg|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
# Nginx
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
Para archivos HTML, utilice tiempos de caché más cortos (max-age=0, must-revalidate) o ETags para la validación de actualización.
Trabajadores de servicio para fuera de línea primero
Los trabajadores del servicio actúan como un proxy de red programable en el navegador:
// service-worker.js
const CACHE_NAME = 'v1';
const urlsToCache = ['/', '/styles.css', '/app.js'];
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 => {
// Cache-first strategy for static assets
return response || fetch(event.request);
})
);
});
Estrategias de almacenamiento en caché del trabajador del servicio:
| Estrategia | Caso de uso |
|---|---|
| Caché primero | Activos estáticos (imágenes, CSS, JS) |
| Red primero | Llamadas API, contenido dinámico. |
| Obsoleto mientras se revalida | Feeds de noticias, publicaciones de blogs |
| Sólo red | Formularios, API de pago |
Almacenamiento en caché perimetral de CDN
Una CDN (Red de entrega de contenidos) almacena en caché el contenido en servidores perimetrales distribuidos geográficamente. Proveedores populares:
- Cloudflare: red global, protección DDoS, compatibilidad con HTTP/3.
- Rápido: purga en tiempo real, configuración de VCL.
- Akamai: nivel empresarial y escala masiva.
- AWS CloudFront: integración profunda de AWS, Lambda@Edge.
Impacto: el almacenamiento en caché de CDN reduce la carga del servidor en más de un 80 % y reduce la latencia entre un 50 y un 80 % para los usuarios globales.
3. Reducir los recursos que bloquean el renderizado
El análisis de HTML se detiene cuando el navegador encuentra etiquetas <script> o <link rel="stylesheet">. Esto bloquea la renderización.
Aplazar y asíncrono
<!-- Async: download in parallel, execute as soon as downloaded -->
<script async src="analytics.js"></script>
<!-- Defer: download in parallel, execute in order after HTML parsing -->
<script defer src="app.js"></script>
Regla de oro:
- Utilice
diferirpara scripts que necesiten acceso DOM y orden de ejecución. - Utilice
asyncpara scripts independientes (análisis, anuncios). - No utilice ninguno de los dos para scripts críticos que deben ejecutarse inmediatamente.
Incorporación de CSS crítico
Extraiga y inserte CSS necesario para el contenido de la mitad superior de la página:
<head>
<style>
/* Inlined critical CSS */
header { background: #333; color: white; }
.hero { min-height: 80vh; display: flex; align-items: center; }
/* ... only what's visible on initial load */
</style>
<!-- Deferred non-critical CSS -->
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
</head>
Herramientas: Critical (Node.js), Penthouse y webpack-critical generan CSS en línea automáticamente.
Consejos de recursos
<!-- Preload critical resources early -->
<link rel="preload" href="hero-image.webp" as="image">
<!-- Preconnect to third-party origins -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://api.example.com">
<!-- Prefetch resources needed on the next page -->
<link rel="prefetch" href="next-page.html">
4. Optimice la ruta de renderizado crítica
La ruta de representación crítica es la secuencia de pasos que sigue el navegador para representar una página. Optimizarlo reduce el tiempo de interacción.
Tiempo de respuesta del servidor
- Mantenga el tiempo hasta el primer byte (TTFB) por debajo de 200 ms.
- Utilice el almacenamiento en caché del lado del servidor (Varnish, Redis, Memcached).
- Elija hosting y bases de datos rápidos.
- Utilice una CDN para contenido dinámico estático y almacenado en caché.
HTTP/2 y HTTP/3
| Protocolo | Características clave |
|---|---|
| HTTP/1.1 | Una solicitud por conexión (limitada) |
| HTTP/2 | Multiplexación, inserción de servidor, compresión de encabezados, protocolo binario |
| HTTP/3 | La conexión RTT cero basada en QUIC maneja mejor la pérdida de paquetes |
HTTP/2 hace que la agrupación sea menos crítica: puede servir muchos archivos pequeños sin la sobrecarga de conexión de HTTP/1.1.
Compresión
# Enable Brotli (preferred, ~20% better than Gzip)
brotli on;
brotli_types text/plain text/css application/json application/javascript;
# Fallback Gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
gzip_vary on;
5. Elementos vitales web básicos
Los Core Web Vitals de Google son las tres métricas que más impactan la experiencia del usuario:
LCP (pintura con contenido más grande): objetivo: <2,5 s
Mide el rendimiento de carga. El elemento visible más grande (imagen principal, encabezado) debe renderizarse rápidamente.
Mejoramiento:
- Optimice y precargue la imagen LCP.
- Minimiza los recursos que bloquean el renderizado.
- Utilice una CDN.
- Considere usar
fetchpriority="high"en el elemento LCP:<img src="hero.webp" fetchpriority="high" alt="Hero">
FID (retraso de la primera entrada): objetivo: <100 ms
Mide la interactividad. Reemplazado por INP (Interacción con la siguiente pintura) en 2024.
Mejoramiento:
- Divida tareas largas de JavaScript (>50 ms).
- Utilice Web Workers para cálculos intensivos.
- Aplazar JavaScript no crítico.
CLS (cambio de diseño acumulativo): objetivo: <0,1
Mide la estabilidad visual. Los elementos no deberían cambiar inesperadamente.
Mejoramiento:
- Establezca siempre el "ancho" y el "alto" explícitos en imágenes y vídeos.
- Reserve espacio para anuncios e incrustaciones.
- Utilice
font-display: opcionalpara fuentes personalizadas. - Evite insertar contenido encima del contenido existente.
img, video {
width: 100%;
height: auto;
aspect-ratio: 16 / 9;
}
/* Reserve space for dynamic content */
.ad-container {
min-height: 250px;
}
6. Técnicas avanzadas
Carga diferida
La carga diferida nativa es compatible con todos los navegadores modernos:
<img src="photo.webp" loading="lazy" alt="Lazy loaded image">
<iframe src="map.html" loading="lazy"></iframe>
Para navegadores más antiguos, utilice el observador de intersecciones como alternativa:
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));
Preconexión y captación previa de DNS
<!-- DNS prefetch resolves domain names early -->
<link rel="dns-prefetch" href="//fonts.googleapis.com">
<!-- Preconnect establishes full connection (DNS + TCP + TLS) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
Optimización de fuentes
/* Font-display controls how fonts render while loading */
@font-face {
font-family: 'CustomFont';
src: url('custom-font.woff2') format('woff2');
font-display: swap; /* Show fallback text immediately */
}
/* Subset fonts to include only needed characters */
/* Use variable fonts for multiple weights in one file */
Herramientas de medición
| Herramienta | Tipo | Mejor para |
|---|---|---|
| Faro | Laboratorio | Auditoría y recomendaciones |
| Información de PageSpeed | Laboratorio + Campo | Métricas específicas de Google |
| Prueba de página web | Laboratorio | Análisis detallado de la cascada |
| Herramientas de desarrollo de Chrome | Laboratorio | Red, rendimiento, cobertura. |
| Rendimiento centinela | RON | Monitoreo de usuarios reales |
| RON de perro de datos | RON | Seguimiento del rendimiento de un extremo a otro |
| Calibre | Continuo | Presupuestos de rendimiento y CI |
| Faro CI | CI | Prevenir regresiones |
Presupuestos de desempeño
Establezca un presupuesto de rendimiento para evitar regresiones:
{
"budgets": [
{
"resourceType": "total",
"budget": 500000
},
{
"resourceType": "script",
"budget": 150000
},
{
"resourceType": "image",
"budget": 200000
},
{
"timing": {
"metric": "interactive"
},
"budget": 5000
}
]
}
Conclusión
El rendimiento web es una disciplina continua. Comience con los elementos de mayor impacto:
- Mida su punto de referencia actual: utilice Lighthouse y WebPageTest.
- Optimizar imágenes: mayor beneficio rápido para la mayoría de los sitios.
- Habilite el almacenamiento en caché y la compresión: ganancias fáciles con un alto retorno de la inversión.
- Elimine los recursos que bloquean el procesamiento: posponga JS y CSS crítico en línea.
- Supervise Core Web Vitals: realice un seguimiento en el campo, no solo en el laboratorio.
La optimización del rendimiento nunca se "hace"; requiere atención continua, pero el retorno de la inversión en satisfacción del usuario, conversiones y SEO es sustancial.
Artículos destacados

6 patrones de programación que aprendí de ingenieros senior

Crea un asistente privado de notas con IA
Convierte notas Markdown en un asistente consultable sin exponer borradores privados.

Automatiza la extracción de datos de facturas con OCR
Crea un flujo que lee facturas, extrae campos y marca valores dudosos para revisión.
Comentarios
0 comentariosTodavía no hay comentarios aprobados. Las respuestas nuevas pueden esperar moderación.