W3docs

Carga de recursos en JavaScript: onload y onerror

Aprende cómo los eventos onload y onerror detectan cuándo imágenes, scripts y hojas de estilo terminan de cargarse o fallan, con ejemplos ejecutables.

Los recursos externos — imágenes, scripts, hojas de estilo, iframes — se cargan de forma asíncrona e independiente del JavaScript que los solicita. El navegador inicia la descarga y tu código sigue ejecutándose; el recurso puede no estar listo durante milisegundos o segundos. Para saber cuándo un recurso está listo (o que ha fallado), todo elemento cargable dispara dos eventos: load cuando tiene éxito y error cuando falla. Esta página muestra cómo usarlos con las propiedades de manejador onload / onerror.

Esto está estrechamente relacionado con el ciclo de vida a nivel de página tratado en DOMContentLoaded, load, beforeunload, unload, y con las estrategias de carga en Scripts: async, defer.

Manejo de la carga de recursos con el evento onload

¿Qué es el evento onload?

El evento load se dispara en un elemento cuando su recurso ha terminado de descargarse completamente y está listo para usarse. Puedes escucharlo de dos maneras equivalentes:

// 1. Handler property (only one handler allowed)
img.onload = () => { /* ... */ };

// 2. addEventListener (multiple handlers allowed)
img.addEventListener('load', () => { /* ... */ });

La forma de propiedad (onload) es conveniente pero solo almacena un único manejador — asignar uno nuevo sobreescribe el anterior. Prefiere addEventListener('load', ...) cuando más de un fragmento de código necesite estar al tanto del mismo recurso.

Un punto importante a tener en cuenta: para un <img>, el evento load cubre únicamente los bytes de esa imagen en particular. No es el window.onload a nivel de página, que espera a todos los recursos. No confundas los dos.

Ejemplo: mostrar una imagen tras la carga completa

Para ilustrarlo, considera un escenario en el que deseas mostrar una imagen solo después de que se haya cargado completamente, para evitar mostrar una imagen parcial o rota.

<div>Here you see the w3docs logo when the page is loaded.</div>
<br />
<div id="imageContainer" style="background-color: grey;"></div>
<script>
document.addEventListener('DOMContentLoaded', function() {
    var img = new Image();
    img.onload = function() {
        document.getElementById('imageContainer').appendChild(img);
    };
    img.src = 'https://www.w3docs.com/build/images/logo-color-w3.png';
});
</script>

Este script garantiza que la imagen se añada al div #imageContainer solo después de haberse cargado completamente, mejorando la experiencia del usuario al evitar mostrar una imagen incompleta.

Advertencia

Establece img.onload antes de img.src. El navegador puede servir una imagen en caché tan rápido que la carga finalice en el mismo ciclo en que se asigna el src — si el manejador aún no está adjunto, perderás el evento por completo.

Uso del evento onerror para el manejo de errores

¿Qué es el evento onerror?

El evento onerror es esencial para un desarrollo web robusto. Se activa cuando ocurre un error durante la carga de un recurso externo, como un script o una imagen. Este evento es fundamental para manejar los errores de forma elegante y garantizar que la experiencia del usuario no se vea interrumpida.

Ejemplo: manejo de errores ante una imagen que no se carga

Considera un escenario en el que una imagen no se carga debido a un enlace roto o un problema del servidor. Usando el evento onerror, puedes proporcionar una solución alternativa o notificar al usuario. En el siguiente ejemplo, el src roto activa el manejador de error en cuanto la página se ejecuta, porque el enlace de la imagen no apunta a un archivo real.

Un recurso dispara ya sea load o error, pero nunca ambos. Por eso puedes adjuntar manejadores para cada uno y confiar en que exactamente uno de ellos se ejecutará.

<div>If there was no error, you could see an image below. But it's a broken link!</div>
<br />
<div id="imageContainer" style="background-color: grey;"></div>
<script>
const img = new Image();
const imageContainer = document.getElementById('imageContainer');
img.onerror = function() {
    imageContainer.innerHTML = 'An error happened.';
};
img.onload = function() {
    imageContainer.appendChild(img);
};
img.src = 'https://www.w3docs.com/build/images/broken-link.png';
</script>

En este ejemplo, si la imagen no se carga, el contenedor muestra un mensaje alternativo en lugar del icono de imagen rota, gestionando el error de forma transparente.

Información

onerror solo se dispara ante fallos de recurso — un 404, una solicitud bloqueada, un error DNS o un archivo corrupto. No se dispara si un script cargado correctamente lanza una excepción en tiempo de ejecución; eso lo reporta el manejador global window.onerror / window.addEventListener('error', ...).

Ejemplo: cargar un script o una hoja de estilo

El mismo patrón se aplica a los elementos <script> y <link>. Puedes crearlos dinámicamente y adjuntar manejadores onload/onerror:

<script>
function loadScript(url) {
    const script = document.createElement('script');
    script.src = url;
    script.onload = () => console.log('Script loaded successfully');
    script.onerror = () => console.error('Failed to load script');
    document.head.appendChild(script);
}
loadScript('https://example.com/app.js');

function loadStylesheet(url) {
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = url;
    link.onload = () => console.log('Stylesheet loaded successfully');
    link.onerror = () => console.error('Failed to load stylesheet');
    document.head.appendChild(link);
}
loadStylesheet('https://example.com/styles.css');
</script>

Los scripts creados dinámicamente se comportan como scripts async: se descargan en paralelo y se ejecutan en cuanto llegan, por lo que el orden de carga no está garantizado. Si un script depende de otro, encadénalos dentro del onload del primer script.

Ejemplo: envolver load/error en una Promise

Para código moderno, envolver los dos eventos en una Promise te ofrece la ergonomía de async/await y un único lugar para gestionar el fallo:

function loadScript(src) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = src;
    script.onload = () => resolve(script);
    script.onerror = () => reject(new Error(`Failed to load: ${src}`));
    document.head.append(script);
  });
}

// Usage
loadScript('https://example.com/app.js')
  .then(() => console.log('Ready to use the script'))
  .catch((err) => console.error(err.message));

Dado que load y error son mutuamente excluyentes, la Promise se resuelve exactamente una vez — ya sea como resuelta o rechazada.

Optimización del rendimiento web mediante el manejo de eventos

Optimizar el rendimiento web implica gestionar las secuencias de carga de recursos y manejar los fallos de forma elegante. Los eventos onload y onerror son especialmente valiosos para la inyección dinámica de recursos. En lugar de codificar todos los activos directamente en el HTML, puedes cargar recursos no críticos bajo demanda. Cuando un recurso no se carga, el evento onerror se activa, lo que te permite implementar lógica alternativa — como sustituir una imagen rota por un marcador de posición o reintentar la carga de un script fallido. Al combinar estos eventos con la renderización progresiva, garantizas que el contenido crítico aparezca de inmediato mientras los activos secundarios se cargan en segundo plano, manteniendo una experiencia de usuario fluida incluso bajo condiciones de red deficientes.

Conclusión

Comprender e implementar los eventos onload y onerror en JavaScript es fundamental para cualquier desarrollador web que busque mejorar la fiabilidad y el rendimiento de sus aplicaciones web. Al emplear estos eventos de forma efectiva, los desarrolladores pueden garantizar que los recursos se gestionen de manera eficiente, mejorando tanto el rendimiento como la experiencia del usuario en sus sitios web. Los ejemplos proporcionados ofrecen un punto de partida para implementar estas técnicas en diversos escenarios, fomentando una comprensión más profunda y el dominio de la carga de recursos en JavaScript.

Práctica

Práctica
¿Cuáles afirmaciones sobre los eventos 'onload' y 'onerror' son correctas?
¿Cuáles afirmaciones sobre los eventos 'onload' y 'onerror' son correctas?
Was this page helpful?