Preload y Lazy Loading: Conceptos, Implementación y Mejores Prácticas
¿Qué es Preload?
El atributo <link rel="preload"> le indica al navegador que descargue un recurso antes de que sea requerido por el árbol de renderizado. Es útil para recursos críticos como fuentes, scripts o CSS que bloquean la primera pintura.
Ejemplo básico:
<link rel="preload" href="/css/critical.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/css/critical.css"></noscript>
El atributo as ayuda al navegador a asignar la prioridad adecuada y aplicar políticas de seguridad (CSP).
¿Qué es Lazy Loading?
Lazy Loading (carga diferida) retrasa la descarga de recursos que no son visibles en el viewport inicial, como imágenes, iframes o videos. El objetivo es reducir el time‑to‑first‑byte y el consumo de ancho de banda.
Desde HTML 5.2, se puede habilitar con el atributo loading="lazy":
<img src="/images/galeria/01.jpg" alt="Foto 1" loading="lazy">
<iframe src="https://www.youtube.com/embed/XYZ" loading="lazy"></iframe>
Para navegadores que no soportan el atributo, se recurre a IntersectionObserver como fallback.
Comparativa rápida
Preload
- Descarga anticipada de recursos críticos.
- Mejora First Contentful Paint (FCP) y Largest Contentful Paint (LCP).
- Se usa con
rel="preload"+as(style, script, font, image, fetch). - Requiere gestión cuidadosa para no saturar la red.
Lazy Loading
- Descarga pospuesta hasta que el recurso entra en el viewport.
- Reduce payload inicial y CPU en dispositivos móviles.
- Se habilita con
loading="lazy"o mediante IntersectionObserver. - Ideal para imágenes, iframes y videos de gran tamaño.
Implementación práctica en HTML
1. Preload de fuentes web
<link rel="preload" href="/fonts/Inter-Variable.woff2" as="font" type="font/woff2" crossorigin>
Al pre‑cargar la fuente, el navegador la tiene disponible antes de que el CSS la solicite, evitando el FOIT (Flash of Invisible Text).
2. Preload de scripts críticos
<link rel="preload" href="/js/critical.js" as="script">
<script src="/js/critical.js" defer></script>
Combínalo con defer o async para que el script se ejecute una vez descargado sin bloquear el parser.
3. Lazy Loading de imágenes con fallback
<img src="/images/placeholder.jpg" data-src="/images/alta-resolucion.jpg" alt="Ejemplo" class="lazyload">
<script>
if ('loading' in HTMLImageElement.prototype) {
document.querySelectorAll('img[data-src]').forEach(img => {
img.src = img.dataset.src;
});
} else {
// IntersectionObserver fallback
const observer = new IntersectionObserver((entries, obs) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
obs.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));
}
</script>
Este patrón garantiza compatibilidad con navegadores antiguos.
Compatibilidad y soporte de navegadores
- Preload: Chrome 73+, Edge 79+, Firefox 75+, Safari 14+ (con
aslimitado astyleyscript). - Lazy Loading (atributo loading): Chrome 76+, Edge 79+, Firefox 75+ (a partir de 2021), Safari 15+.
- Para navegadores sin soporte, utilice polyfills basados en
IntersectionObserver(compatible con IE 11 mediante polyfill).
Seguridad y CSP
Cuando se usa rel="preload", es importante declarar la política de seguridad de contenidos (CSP) de forma adecuada:
Content-Security-Policy: preload-src https: 'self';
Content-Security-Policy: font-src 'self' https://fonts.gstatic.com;
Esto evita que recursos externos maliciosos sean pre‑cargados sin autorización.
Diagnóstico y herramientas de troubleshooting
- Chrome DevTools → Network: Filtre por
initiatorpara ver qué recursos se cargaron via preload. - Lighthouse: Revisa la sección “Avoid large layout shifts” y “Serve static assets with an efficient cache policy”.
- WebPageTest: Observe el “Start render” y “Speed Index” antes y después de aplicar preload/lazy.
Si un recurso pre‑cargado nunca se usa, elimínelo para no desperdiciar ancho de banda.
Mejores prácticas y checklist
- Identifique los recursos críticos (fuentes, CSS, scripts esenciales) y aplique
preload. - Limite la cantidad de preloads a 3‑5 por página para evitar saturar la conexión.
- Utilice
loading="lazy"en todas las imágenes y iframes que no estén visibles al cargar. - Implemente un fallback con IntersectionObserver para navegadores sin soporte.
- Compruebe la compatibilidad con CSP y añada los dominios necesarios.
- Monitoree el impacto en LCP y CLS mediante Lighthouse o PageSpeed Insights.
Casos de uso del mundo real
E‑commerce: Preload del CSS de la página de producto y lazy loading de la galería de fotos.
Blogs y sitios de contenido: Preload de la fuente principal y lazy loading de imágenes embebidas en artículos largos.
Aplicaciones SaaS: Preload de scripts de autenticación y lazy loading de módulos de UI que se cargan bajo demanda.
Preload vs Lazy Loading: Guía completa con ejemplos en HTML