Cómo cargar imágenes de forma dinámica (o perezosa) cuando los usuarios las desplazan para verlas

97

He notado esto en numerosos sitios web "modernos" (p. Ej., Búsqueda de imágenes de Facebook y Google) donde las imágenes debajo de la página se cargan solo cuando el usuario se desplaza hacia abajo en la página lo suficiente como para traerlas dentro de la región de la ventana gráfica visible ( al ver la fuente, la página muestra X número de <img>etiquetas, pero no se obtienen del servidor de inmediato ). Cómo se llama esta técnica, cómo funciona y en cuántos navegadores funciona. ¿Y hay un complemento jQuery que pueda lograr este comportamiento con una codificación mínima?

Editar

Bono: ¿alguien puede explicar si hay un evento "onScrolledIntoView" o similar para elementos HTML? Si no es así, ¿cómo funcionan estos complementos?

Salman A
fuente
¿Necesita solo una carga diferida de imágenes? Si necesita carga diferida de contenido, el complemento de desplazamiento infinito es la respuesta correcta
soju
@rsp @jwegner @Nicholas lo siento, pero eso no es lo que está preguntando Salman.
Alec Smart
@soju: Solo me interesan las imágenes de carga diferida; pero puedo considerar otras posibilidades en algún momento del futuro (bastante lejano).
Salman A
21
Hace que te preguntes por qué el comportamiento predeterminado de un navegador no es solo cargar imágenes que son visibles. ¡Imagínese cuánto ancho de banda se podría haber ahorrado en los últimos 18 años si ese fuera el caso!
Matthew Lock
2
Si bien entiendo la razón detrás de la carga diferida ... honestamente, no puedo soportarlo cuando visito un sitio que utiliza ese método. ¡El parpadeo de las imágenes me vuelve loco! :)
Booski

Respuestas:

64

Algunas de las respuestas aquí son para páginas infinitas. Lo que está preguntando Salman es la carga lenta de imágenes.

Enchufar

Manifestación

EDITAR: ¿Cómo funcionan estos complementos?

Esta es una explicación simplificada:

  1. Encuentre el tamaño de la ventana y encuentre la posición de todas las imágenes y sus tamaños
  2. Si la imagen no está dentro del tamaño de la ventana, reemplácela con un marcador de posición del mismo tamaño
  3. Cuando el usuario se desplaza hacia abajo y la posición de la imagen <desplazamiento + altura de la ventana, la imagen se carga
Alec inteligente
fuente
En la aplicación, ¿no funcionarían igual? Un desplazamiento infinito en una sola columna de imágenes sería lo mismo que cargarlas de forma diferida, ¿verdad? Quizás estoy confundido.
jwegner
1
@jwegner Infinite scroll le permitiría agregar nuevos elementos al final de la página cuando el usuario llegó (o se acercó) al final. Las imágenes cargadas de forma diferida podrían tener marcadores de posición de las mismas dimensiones en la página, con las propias imágenes cargadas en el desplazamiento. Por lo tanto, este último podría cargarse sin afectar el diseño de la página.
Annika Backstrom
Esto funciona bien en navegadores de escritorio e iOS, pero no funciona en Android (incluido 3.x / 4.x). ¿Alguna idea de por qué? ¿No se admite el evento de desplazamiento?
lahsrah
Estaba revisando la documentación de este complemento y parece bastante impresionante. Voy a usar esto en mi próximo proyecto.
The Muffin Man
aquí hay un complemento relacionado, que probablemente funcione de la misma manera: afarkas.github.io/lazysizes excepto que creo que es mucho más robusto y usa más de lo que ya está allí (no es necesario un marcador de posición, por ejemplo, pero puede tenerlo si querer).
cregox
10

Dave Artz de AOL dio una gran charla sobre optimización en jQuery Conference Boston el año pasado. AOL utiliza una herramienta llamada Sonar para la carga bajo demanda basada en la posición de desplazamiento. Verifique el código para conocer los detalles de cómo compara scrollTop (y otros) con el desplazamiento del elemento para detectar si parte o todo el elemento es visible.

Sonda jQuery

Dave habla de Sonar en estas diapositivas . Sonar comienza en la diapositiva 46, mientras que la discusión general sobre "carga a pedido" comienza en la diapositiva 33.

Annika Backstrom
fuente
Me pregunto cómo se compara esto con la carga perezosa de Appelsinii. ¿Es más ligero? ¿Funciona en todos los navegadores? Recuerdo que lazyload no funciona en Chrome.
Deathlock
8

Se me ocurrió mi propio método básico que parece funcionar bien (hasta ahora). Probablemente haya una docena de cosas que algunos de los scripts populares abordan en las que no he pensado.

Nota : esta solución es rápida y fácil de implementar pero, por supuesto, no es excelente para el rendimiento. Definitivamente, busque en el nuevo Intersection Observer mencionado por Apoorv y explicado por developers.google si el rendimiento es un problema.

El 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');
        }
    })
})

Ejemplo de código html

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

Explicado

Cuando se desplaza la página, se comprueba cada imagen de la página.

$(this).attr('data-src') - si la imagen tiene el atributo data-src

y qué tan lejos están esas imágenes de la parte inferior de la ventana.

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

ajusta el + 100 a lo que quieras (- 100 por ejemplo)

var source = $(this).data('src');- obtiene el valor de data-src=también conocido como la URL de la imagen

$(this).attr('src', source); - pone ese valor en el src=

$(this).removeAttr('data-src'); - elimina el atributo data-src (para que su navegador no desperdicie recursos jugando con las imágenes que ya se han cargado)

Agregar al código existente

Para convertir su html, en un editor simplemente busque y reemplace src="consrc="" data-src="

Hastig Zusammenstellen
fuente
Perfecto. bendiga a la familia 🙏
LifterCoder
5

Hay un bonito bastante infinita de desplazamiento plugin de aquí

Nunca he programado uno yo mismo, pero me imagino que así es como funciona.

  1. Un evento está vinculado al desplazamiento de la ventana.

    $(window).scroll(myInfinteScrollFunction);
  2. La función llamada comprueba si la parte superior de desplazamiento es mayor que el tamaño de la ventana

    function myInfiniteScrollFunction() {  
        if($(window).scrollTop() == $(window).height())  
        makeAjaxRequest();  
    }
  3. Se realiza una solicitud AJAX, especificando en qué número de resultado comenzar, cuántos tomar y cualquier otro parámetro necesario para la extracción de datos.

    $.ajax({
        type: "POST",
        url:  "myAjaxFile.php",
        data: {"resultNum": 30, "numPerPage": 50, "query": "interesting%20icons" },
        success: myInfiniteLoadFunction(msg)
    });
  4. El ajax devuelve algún contenido (probablemente con formato JSON) y lo pasa a la función loadnig.

Espero que tenga sentido.

jwegner
fuente
3

La carga diferida de imágenes al adjuntar el oyente a los eventos de desplazamiento o al hacer uso de setInterval es muy poco eficaz, ya que cada llamada a getBoundingClientRect () obliga al navegador a rediseñar la página completa e introducirá un jank considerable en su sitio web.

Use Lozad.js (solo 569 bytes sin dependencias), que usa IntersectionObserver para cargar imágenes de forma diferida.

Apoorv Saxena
fuente
Polyfill se puede agregar dinámicamente en caso de que el soporte del navegador no esté disponible
Apoorv Saxena
El soporte del navegador es mucho mejor en estos días, ¿ puedo usarlo
Hastig Zusammenstellen
1

La navaja suiza de carga diferida de imágenes es ImageLoader de YUI .

Porque hay más en este problema que simplemente observar la posición de desplazamiento.

Arnaud Meuret
fuente
0

Este enlace funciona para mi demostración

1.Cargue el complemento jQuery loadScroll después de la biblioteca jQuery, pero antes de la etiqueta del cuerpo de cierre.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script><script src="jQuery.loadScroll.js"></script>

2.Agregue las imágenes en su página web usando el atributo Html5 data-src. También puede insertar marcadores de posición utilizando el atributo src de img regular.

<img data-src="1.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="2.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="3.jpg" src="Placeholder.jpg" alt="Image Alt">

3. Llame al complemento en las etiquetas img y especifique la duración del efecto de desvanecimiento a medida que sus imágenes aparecen

$('img').loadScroll(500); // in ms
vebs
fuente
0

Estoy usando jQuery Lazy . Me tomó alrededor de 10 minutos para poner a prueba y una o dos horas para agregar a la mayoría de los enlaces de imagen en uno de mis sitios web ( CollegeCarePackages.com ). No tengo ninguna relación (ninguna / cero) de ningún tipo con el desarrollador, pero me ahorró mucho tiempo y básicamente ayudó a mejorar nuestra tasa de rebote para los usuarios de dispositivos móviles y se lo agradezco.

Acantilado Ribaudo
fuente