Soy plenamente consciente de que esta pregunta se ha formulado y respondido en todas partes, tanto con SO como sin ella. Sin embargo, cada vez parece haber una respuesta diferente, p. esto, this y eso.

No me importa si está usando jQuery o no, lo importante es que funciona y es un navegador cruzado.]

Entonces, ¿cuál es la mejor manera de precargar imágenes?

50
Skilldrick 23 may. 2009 a las 19:02

6 respuestas

La mejor respuesta

Desafortunadamente, eso depende de tu propósito. Si planea usar las imágenes con fines de estilo, su mejor opción es usar sprites. http://www.alistapart.com/articles/sprites2

Sin embargo, si planea usar las imágenes en etiquetas , entonces querrá precargarlas con

function preload(sources)
{
  var images = [];
  for (i = 0, length = sources.length; i < length; ++i) {
    images[i] = new Image();
    images[i].src = sources[i];
  }
}

(fuente modificada tomada de ¿Cuál es el ¿La mejor manera de precargar varias imágenes en JavaScript?)

El uso de new Image() no implica el gasto del uso de métodos DOM, pero se agregará a la cola una nueva solicitud para la imagen especificada. Como la imagen, en este momento, no se agrega realmente a la página, no hay que volver a representarla. Sin embargo, recomendaría agregar esto al final de su página (como deberían ser todos sus scripts, cuando sea posible) para evitar que contenga elementos más críticos.

Editar: Editado para reflejar el comentario de forma bastante correcta, señalando que se requieren objetos Image separados para funcionar correctamente. Gracias, y mi mal por no comprobarlo más de cerca.

Edit2: editado para que la reutilización sea más obvia

Editar 3 (3 años después):

Debido a los cambios en la forma en que los navegadores manejan las imágenes no visibles (pantalla: ninguna o, como en esta respuesta, nunca adjuntas al documento), se prefiere un nuevo enfoque para la carga previa.

Puede utilizar una solicitud de Ajax para forzar la recuperación temprana de imágenes. Usando jQuery, por ejemplo:

jQuery.get(source);

O en el contexto de nuestro ejemplo anterior, podría hacer:

function preload(sources)
{
  jQuery.each(sources, function(i,source) { jQuery.get(source); });
}

Tenga en cuenta que esto no se aplica al caso de los sprites que están bien como están. Esto es solo para cosas como galerías de fotos o deslizadores / carruseles con imágenes donde las imágenes no se cargan porque inicialmente no son visibles.

También tenga en cuenta que este método no funciona para IE (ajax normalmente no se utiliza para recuperar datos de imagen).

66
Community 23 may. 2017 a las 11:46

Esto fue hace mucho tiempo, así que no sé cuántas personas todavía están interesadas en precargar una imagen.

Mi solución fue aún más simple.

Acabo de usar CSS.

#hidden_preload {
    height: 1px;
    left: -20000px;
    position: absolute;
    top: -20000px;
    width: 1px;
}
1
Scott Cleland 12 abr. 2015 a las 20:45

A partir de enero de 2013, ninguno de los métodos descritos aquí funcionó para mí, así que esto es lo que hizo, probó y trabajó con Chrome 25 y Firefox 18. Utiliza jQuery y este complemento para solucionar las peculiaridades del evento de carga:

function preload(sources, callback) {
    if(sources.length) {
        var preloaderDiv = $('<div style="display: none;"></div>').prependTo(document.body);

        $.each(sources, function(i,source) {
            $("<img/>").attr("src", source).appendTo(preloaderDiv);

            if(i == (sources.length-1)) {
                $(preloaderDiv).imagesLoaded(function() {
                    $(this).remove();
                    if(callback) callback();
                });
            }
        });
    } else {
        if(callback) callback();
    }
}

Uso:

preload(['/img/a.png', '/img/b.png', '/img/c.png'], function() { 
    console.log("done"); 
});

Tenga en cuenta que obtendrá resultados mixtos si la memoria caché está deshabilitada, que está en Chrome de manera predeterminada cuando las herramientas de desarrollador están abiertas, así que tenga esto en cuenta.

6
Mahn 26 ene. 2013 a las 15:17

Para mi caso de uso, tenía un carrusel con imágenes de pantalla completa que quería precargar. Sin embargo, dado que las imágenes se muestran en orden y pueden tardar unos segundos en cargarse, es importante que las cargue en orden, secuencialmente.

Para esto utilicé el método waterfall() de la biblioteca asíncrona (https://github.com/caolan/async #waterfall)

        // Preload all images in the carousel in order.
        image_preload_array = [];
        $('div.carousel-image').each(function(){
            var url = $(this).data('image-url');
            image_preload_array.push(function(callback) {
                var $img = $('<img/>')
                $img.load(function() {
                    callback(null);
                })[0].src = url;
            });
        });
        async.waterfall(image_preload_array);

Esto funciona creando una matriz de funciones, a cada función se le pasa el parámetro callback() que necesita ejecutar para llamar a la siguiente función en la matriz. El primer parámetro de callback() es un mensaje de error, que saldrá de la secuencia si se proporciona un valor no nulo, por lo que pasamos nulo cada vez.

0
DanH 23 sep. 2014 a las 03:13

Aquí va mi solución simple con un fundido en la imagen después de que se carga.

    function preloadImage(_imgUrl, _container){
        var image = new Image();
            image.src = _imgUrl;
            image.onload = function(){
                $(_container).fadeTo(500, 1);
            };
        }
0
Afonso Praça 29 ene. 2013 a las 02:44

Mira esto:

http://www.mattfarina.com/2007/02/01/preloading_images_with_jquery

Pregunta relacionada sobre SO:

precarga oculta jquery

-2
Community 23 may. 2017 a las 12:02