102 votes

Comment charger les images de manière dynamique (ou paresseuse) lorsque les utilisateurs les font défiler à l'écran ?

J'ai remarqué ce phénomène sur de nombreux sites web "modernes" (par exemple facebook et google image search) où les images sous le pli ne se chargent que lorsque l'utilisateur fait suffisamment défiler la page pour les amener dans la zone visible de la fenêtre ( à la vue de la source, la page affiche X nombre de <img> mais ils ne sont pas récupérés directement du serveur. ). Comment s'appelle cette technique, comment fonctionne-t-elle et dans combien de navigateurs fonctionne-t-elle ? Et existe-t-il un plugin jQuery qui permet d'obtenir ce comportement avec un codage minimal ?

Modifier

Bonus : quelqu'un peut-il expliquer s'il existe un événement "onScrolledIntoView" ou similaire pour les éléments HTML. Si non, comment ces plugins fonctionnent-ils ?

0 votes

Avez-vous besoin d'un chargement paresseux des images uniquement ? Si vous avez besoin d'un chargement paresseux du contenu, le plugin infinite scroll est la bonne réponse.

0 votes

@rsp @jwegner @Nicholas Je suis désolé, mais ce n'est pas ce que Salman demande.

0 votes

@soju : Je ne suis intéressé que par le chargement paresseux des images ; mais je pourrais envisager d'autres possibilités dans un avenir (assez lointain).

67voto

Alec Smart Points 14075

Certaines des réponses ici sont pour la page infinie. Ce que Salman demande, c'est le chargement paresseux des images.

Plugin

Démo

EDIT : Comment ces plugins fonctionnent-ils ?

Il s'agit d'une explication simplifiée :

  1. Trouver la taille de la fenêtre et trouver la position de toutes les images et leurs tailles
  2. Si l'image ne correspond pas à la taille de la fenêtre, remplacez-la par une image de même taille.
  3. Lorsque l'utilisateur fait défiler vers le bas et que la position de l'image est < défilement + hauteur de la fenêtre, l'image est chargée.

0 votes

Dans l'application, ne fonctionneraient-ils pas de la même manière ? Un défilement infini sur une seule colonne d'images reviendrait à les charger paresseusement, non ? Peut-être suis-je confus.

1 votes

@jwegner Le défilement infini vous permettrait d'ajouter de nouveaux éléments au bas de la page lorsque l'utilisateur atteint (ou s'approche) du bas. Les images chargées paresseusement pourraient avoir des espaces réservés de mêmes dimensions sur la page, les images elles-mêmes étant chargées lors du défilement. Ainsi, ces dernières pourraient se charger paresseusement sans affecter la mise en page.

0 votes

Cela fonctionne bien sur les navigateurs de bureau et iOS mais pas sur Android (y compris 3.x/4.x). Savez-vous pourquoi ? L'événement de défilement n'est-il pas pris en charge ?

15voto

J'ai mis au point ma propre méthode de base qui semble fonctionner correctement (jusqu'à présent). Il y a probablement une douzaine de choses que certains des scripts populaires abordent et auxquelles je n'ai pas pensé.

Note - Cette solution est rapide et facile à mettre en œuvre mais, bien sûr, elle n'est pas très performante. Il faut absolument se pencher sur la nouvelle Observateur d'intersections comme indiqué par Apoorv et expliqué par développeurs.google si la performance est un problème.

L'application JQuery

$(window).scroll(function() {
    $.each($('img'), function() {
        if ( $(this).attr('data-src') && $(this).offset().top < ($(window).scrollTop() + $(window).height() + 100) ) {
            var source = $(this).data('src');
            $(this).attr('src', source);
            $(this).removeAttr('data-src');
        }
    })
})

Exemple de code html

<div>
    <img src="" data-src="pathtoyour/image1.jpg">
    <img src="" data-src="pathtoyour/image2.jpg">
    <img src="" data-src="pathtoyour/image3.jpg">
</div>

Expliqué

Lorsque la page est déroulée, chaque image de la page est vérifiée

$(this).attr('data-src') - si l'image a l'attribut data-src

et à quelle distance ces images sont du bas de la fenêtre

$(this).offset().top < ($(window).scrollTop() + $(window).height() + 100)

Ajustez le + 100 à ce que vous voulez (- 100 par exemple).

var source = $(this).data('src'); - obtient la valeur de data-src= alias l'url de l'image

$(this).attr('src', source); - met cette valeur dans le src=

$(this).removeAttr('data-src'); - supprime l'attribut data-src (pour que votre navigateur ne gaspille pas de ressources à s'occuper des images déjà chargées).

Ajout au code existant

Pour convertir votre html, dans un éditeur il suffit de chercher et remplacer src=" avec src="" data-src="

10voto

Annika Backstrom Points 8138

( Editar: remplacé les liens cassés par des copies archivées)

Dave Artz, d'AOL, a donné un excellent exposé sur l'optimisation lors de la conférence jQuery de Boston l'année dernière. AOL utilise un outil appelé Sonar pour le chargement à la demande en fonction de la position du défilement. Consultez le code pour savoir comment il compare scrollTop (et d'autres) au décalage de l'élément pour détecter si une partie ou la totalité de l'élément est visible.

jQuery Sonar

Dave parle de Sonar dans ces diapositives . Le Sonar commence à la diapositive 46, tandis que la discussion générale sur la "charge à la demande" commence à la diapositive 33.

0 votes

Je me demande comment cela se compare à la charge de paresse d'Appelsinii ? Est-il plus léger ? Fonctionne-t-il sur tous les navigateurs ? Je me souviens que lazyload ne fonctionne pas sur Chrome.

5voto

jwegner Points 1736

Il existe un plugin de défilement infini très intéressant. aquí

Je n'en ai jamais programmé moi-même, mais j'imagine que c'est ainsi que cela fonctionne.

  1. Un événement est lié au défilement de la fenêtre.

    $(window).scroll(myInfinteScrollFunction);
  2. La fonction appelée vérifie si le haut du défilement est supérieur à la taille de la fenêtre.

    function myInfiniteScrollFunction() {  
        if($(window).scrollTop() == $(window).height())  
        makeAjaxRequest();  
    }
  3. Une requête AJAX est effectuée, spécifiant le numéro de résultat à partir duquel il faut commencer, le nombre de résultats à saisir et tout autre paramètre nécessaire pour l'extraction des données.

    $.ajax({
        type: "POST",
        url:  "myAjaxFile.php",
        data: {"resultNum": 30, "numPerPage": 50, "query": "interesting%20icons" },
        success: myInfiniteLoadFunction(msg)
    });
  4. L'ajax renvoie un contenu (le plus souvent formaté en JSON), et le passe à la fonction loadnig.

J'espère que cela a du sens.

3voto

Cody Points 996

Le chargement paresseux des images en attachant un écouteur aux événements de défilement ou en utilisant setInterval est très peu performant car chaque appel à getBoundingClientRect() force le navigateur à re-calculer la page entière et introduira un jank considérable à votre site web.

Utilisez Lozad.js (seulement 569 octets sans aucune dépendance), qui utilise IntersectionObserver pour charger les images de manière paresseuse et performante.

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