50 votes

La meilleure façon de précharger des images en utilisant JavaScript/jQuery ?

Je suis pleinement conscient que cette question a été posée et répondue partout, que ce soit sur SO ou en dehors. Cependant, à chaque fois, il semble y avoir une réponse différente, par ex. este , este y que .

Peu m'importe qu'il utilise jQuery ou non - l'important est qu'il fonctionne et qu'il soit multi-navigateurs].

Alors, quelle est la meilleure façon de précharger les images ?

66voto

Jonathan Fingland Points 26224

Malheureusement, cela dépend de votre objectif. Si vous prévoyez d'utiliser les images à des fins stylistiques, votre meilleure option est d'utiliser des sprites. http://www.alistapart.com/articles/sprites2

Toutefois, si vous prévoyez d'utiliser les images dans les balises <img>, vous voudrez les précharger avec le programme

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

(source modifiée tirée de Quelle est la meilleure façon de précharger plusieurs images en JavaScript ? )

en utilisant new Image() ne nécessite pas l'utilisation des méthodes DOM, mais une nouvelle demande pour l'image spécifiée sera ajoutée à la file d'attente. Comme l'image n'est, à ce stade, pas réellement ajoutée à la page, il n'y a pas de nouveau rendu impliqué. Je recommanderais, cependant, d'ajouter ceci à la fin de votre page (comme tous vos scripts devraient l'être, si possible) pour éviter qu'il ne retarde des éléments plus critiques.

Edit : Edited to reflect comment quite correctly pointing that separate Image sont nécessaires pour fonctionner correctement. Merci, et c'est ma faute si je ne l'ai pas vérifié de plus près.

Edit2 : modifié pour rendre la réutilisabilité plus évidente

Edit 3 (3 ans plus tard) :

En raison des modifications apportées à la manière dont les navigateurs traitent les images non visibles (display:none ou, comme dans cette réponse, jamais ajoutées au document), une nouvelle approche du préchargement est préférable.

Vous pouvez utiliser une requête Ajax pour forcer la récupération rapide des images. En utilisant jQuery, par exemple :

jQuery.get(source);

Ou dans le contexte de notre exemple précédent, vous pourriez faire :

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

Notez que cela ne s'applique pas au cas des sprites qui sont très bien tels quels. C'est juste pour des choses comme les galeries de photos ou les sliders/carrousels avec des images où les images ne se chargent pas parce qu'elles ne sont pas visibles initialement.

Notez également que cette méthode ne fonctionne pas pour IE (ajax n'est normalement pas utilisé pour récupérer des données d'image).

14voto

aleemb Points 12138

Spriting

Comme d'autres l'ont mentionné, le spriting fonctionne assez bien pour diverses raisons, mais il n'est pas aussi bon qu'on le prétend.

  • En revanche, vous ne faites qu'une seule demande HTTP pour vos images. Mais c'est une question de goût.
  • Le revers de la médaille est que vous chargez tout en une seule requête HTTP. Comme la plupart des navigateurs actuels sont limités à deux connexions simultanées, la demande d'image peut bloquer d'autres demandes. Par conséquent, il est possible que l'arrière-plan de votre menu ne s'affiche pas avant un certain temps.
  • Plusieurs images partagent la même palette de couleurs, ce qui permet de faire des économies, mais ce n'est pas toujours le cas et, même dans ce cas, c'est négligeable.
  • La compression est améliorée car il y a plus de données partagées entre les images.

La gestion des formes irrégulières est cependant délicate. La combinaison de toutes les nouvelles images dans la nouvelle est un autre inconvénient.

Approche "low jack" utilisant les balises <img>

Si vous cherchez le le plus définitif Si vous n'avez pas de solution, vous devriez opter pour l'approche "low-jack" que je préfère toujours. Créez des liens <img> vers les images à la fin de votre document et définissez l'attribut width y height à 1x1 pixel et les mettre en plus dans un div caché. S'ils se trouvent à la fin de la page, ils seront chargés après les autres contenus.

6voto

Mahn Points 5565

En janvier 2013, aucune des méthodes décrites ici n'a fonctionné pour moi, alors voici ce qui a fonctionné à la place, testé et fonctionnant avec Chrome 25 et Firefox 18. Utilise jQuery et ce plugin pour contourner les bizarreries de l'événement de chargement :

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"); 
});

Notez que vous obtiendrez des résultats mitigés si le cache est désactivé, ce qui est le cas par défaut sur Chrome lorsque les outils de développement sont ouverts, donc gardez cela à l'esprit.

3voto

Angel Points 31

À mon avis, l'utilisation du XMLHttpRequest multipart introduit par certaines bibliothèques sera une solution privilégiée dans les années à venir. Cependant IE < v8, ne supporte toujours pas data:uri (même IE8 a un support limité, permettant jusqu'à 32kb). Voici une implémentation du préchargement d'images en parallèle. http://code.google.com/p/core-framework/wiki/ImagePreloading Il est inclus dans le framework, mais il vaut la peine d'y jeter un coup d'œil.

0voto

Afonso Praça Points 23

Voici ma solution simple avec un fondu sur l'image après son chargement.

    function preloadImage(_imgUrl, _container){
        var image = new Image();
            image.src = _imgUrl;
            image.onload = function(){
                $(_container).fadeTo(500, 1);
            };
        }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X