Jak ładować obrazy dynamicznie (lub leniwie), gdy użytkownicy przewijają je do widoku

97

Zauważyłem to w wielu "nowoczesnych" witrynach internetowych (np. Na Facebooku i wyszukiwarce grafiki Google), gdzie obrazy poniżej części ekranu ładują się tylko wtedy, gdy użytkownik przewija stronę w dół na tyle, aby przenieść je do widocznego obszaru widoku ( po wyświetleniu źródła strona wyświetla X liczba <img>znaczników, ale nie są one pobierane z serwera od razu ). Jak nazywa się ta technika, jak działa i w ilu przeglądarkach działa. Czy istnieje wtyczka jQuery, która może osiągnąć to zachowanie przy minimalnym kodowaniu.

Edytować

Bonus: czy ktoś może wyjaśnić, czy istnieje „onScrolledIntoView” lub podobne zdarzenie dla elementów HTML. Jeśli nie, jak działają te wtyczki?

Salman A
źródło
Czy potrzebujesz tylko leniwego ładowania obrazu? Jeśli potrzebujesz leniwego ładowania treści, wtyczka nieskończonego przewijania jest właściwą odpowiedzią
soju
@rsp @jwegner @Nicholas Przykro mi, ale nie o to prosi Salman.
Alec Smart,
@soju: Interesuje mnie tylko leniwe ładowanie obrazów; ale mogę przyjrzeć się innym możliwościom kiedyś w (dość odległej) przyszłości.
Salman A,
21
Sprawia, że ​​zastanawiasz się, dlaczego domyślne zachowanie przeglądarki nie polega na ładowaniu tylko widocznych obrazów. Wyobraź sobie, ile przepustowości można by zaoszczędzić w ciągu ostatnich 18 lat, gdyby tak było!
Matthew Lock,
2
Chociaż rozumiem powód leniwego ładowania ... Szczerze mówiąc, nie mogę tego znieść, gdy odwiedzam witrynę, która korzysta z tej metody. Migotanie obrazów doprowadza mnie do szału! :)
Booski,

Odpowiedzi:

64

Niektóre odpowiedzi tutaj dotyczą nieskończonej strony. Salman pyta o leniwe ładowanie obrazów.

Podłącz

Próbny

EDYCJA: Jak działają te wtyczki?

To jest uproszczone wyjaśnienie:

  1. Znajdź rozmiar okna i znajdź położenie wszystkich obrazów i ich rozmiary
  2. Jeśli obraz nie mieści się w rozmiarze okna, zastąp go symbolem zastępczym tego samego rozmiaru
  3. Gdy użytkownik przewinie w dół, a pozycja obrazu <przewiń + wysokość okna, obraz zostanie załadowany
Alec Smart
źródło
Czy w aplikacji nie działałyby tak samo? Nieskończone przewijanie pojedynczej kolumny obrazów byłoby tym samym, co leniwe ładowanie ich, prawda? Może jestem zdezorientowany.
jwegner
1
@jwegner Nieskończone przewijanie umożliwiłoby dodawanie nowych elementów na dole strony, gdy użytkownik osiągnął (lub zbliżył się) do dołu. Obrazy ładowane z opóźnieniem mogą mieć na stronie elementy zastępcze o tych samych wymiarach, a same obrazy ładowane są na przewijaniu. Tak więc ten ostatni może ładować się z opóźnieniem bez wpływu na układ strony.
Annika Backstrom
Działa to dobrze w przeglądarkach stacjonarnych i iOS, ale nie działa na Androidzie (w tym 3.x / 4.x). Każdy pomysł, dlaczego? czy zdarzenie przewijania nie jest obsługiwane?
lahsrah
Przeglądałem dokumentację tej wtyczki i wygląda na to, że jest niesamowita. Zamierzam użyć tego w moim następnym projekcie.
The Muffin Man,
oto powiązana wtyczka, która prawdopodobnie działa w ten sam sposób: afarkas.github.io/lazysizes, z wyjątkiem tego, że uważam, że jest znacznie bardziej niezawodna i wykorzystuje więcej tego, co już istnieje (na przykład nie ma potrzeby stosowania symbolu zastępczego, ale możesz go mieć, jeśli chcieć).
cregox
10

Dave Artz z AOL wygłosił świetną prelekcję na temat optymalizacji podczas zeszłorocznej konferencji jQuery Conference w Bostonie. AOL używa narzędzia o nazwie Sonar do ładowania na żądanie na podstawie pozycji przewijania. Sprawdź kod, aby dowiedzieć się, jak porównuje scrollTop (i inne) z przesunięciem elementu, aby wykryć, czy część lub całość elementu jest widoczna.

jQuery Sonar

Dave mówi o sonarze na tych slajdach . Sonar zaczyna się na slajdzie 46, a ogólna dyskusja na temat „obciążenia na żądanie” zaczyna się na slajdzie 33.

Annika Backstrom
źródło
Zastanawiam się, jak to się ma do lazyload Appelsinii? Czy jest lżejszy? Czy działa na każdej przeglądarce? Pamiętam, że lazyload nie działa w przeglądarce Chrome.
deathlock
8

Wymyśliłem własną podstawową metodę, która wydaje się działać dobrze (na razie). Prawdopodobnie jest tuzin rzeczy, o których nie pomyślałem w niektórych popularnych skryptach.

Uwaga - to rozwiązanie jest szybkie i łatwe do wdrożenia, ale oczywiście nie jest świetne pod względem wydajności. Zdecydowanie spójrz na nowy Intersection Observer, o którym wspomniał Apoorv i wyjaśniony przez developers.google, jeśli wydajność jest problemem.

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

Przykładowy kod html

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

Wyjaśnione

Kiedy strona jest przewijana, każdy obraz na stronie jest sprawdzany.

$(this).attr('data-src') - jeśli obraz ma atrybut data-src

i jak daleko te obrazy są od dołu okna.

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

dostosuj + 100 do tego, co lubisz (na przykład - 100)

var source = $(this).data('src');- pobiera wartość data-src=aka adresu URL obrazu

$(this).attr('src', source); - umieszcza tę wartość w src=

$(this).removeAttr('data-src'); - usuwa atrybut data-src (aby Twoja przeglądarka nie marnowała zasobów na obrazy, które zostały już załadowane)

Dodawanie do istniejącego kodu

Aby przekonwertować HTML w edytorze wystarczy wyszukać i zamienić src="zsrc="" data-src="

Hastig Zusammenstellen
źródło
idealny. bless fam 🙏
LifterCoder
5

Jest to całkiem ładny nieskończonego przewijania plugin tutaj

Nigdy sam takiego nie programowałem, ale wyobrażam sobie, jak to działa.

  1. Zdarzenie jest powiązane z przewijaniem okna

    $(window).scroll(myInfinteScrollFunction);
  2. Wywołana funkcja sprawdza, czy góra przewijania jest większa niż rozmiar okna

    function myInfiniteScrollFunction() {  
        if($(window).scrollTop() == $(window).height())  
        makeAjaxRequest();  
    }
  3. Wykonywane jest żądanie AJAX, określające, od którego wyniku # ma się zacząć, od ilu należy pobrać i wszelkie inne parametry niezbędne do pobierania danych.

    $.ajax({
        type: "POST",
        url:  "myAjaxFile.php",
        data: {"resultNum": 30, "numPerPage": 50, "query": "interesting%20icons" },
        success: myInfiniteLoadFunction(msg)
    });
  4. Ajax zwraca pewną zawartość (najprawdopodobniej sformatowaną w formacie JSON) i przekazuje ją do funkcji loadnig.

Mam nadzieję, że to ma sens.

jwegner
źródło
3

Leniwe ładowanie obrazów przez dołączenie detektora do przewijania zdarzeń lub użycie setInterval jest wysoce niewydajne, ponieważ każde wywołanie metody getBoundingClientRect () zmusza przeglądarkę do zmiany układu całej strony i spowoduje znaczne szarpnięcie w witrynie.

Użyj Lozad.js (tylko 569 bajtów bez zależności), który używa IntersectionObserver do leniwego ładowania obrazów.

Apoorv Saxena
źródło
Polyfill można dodać dynamicznie, jeśli obsługa przeglądarki nie jest dostępna
Apoorv Saxena
Obsługa przeglądarek jest obecnie znacznie lepsza - czy mogę używać
Hastig Zusammenstellen
1

Szwajcarski scyzoryk z funkcją leniwego ładowania obrazu to ImageLoader firmy YUI .

Ponieważ ten problem jest czymś więcej niż tylko obserwowaniem pozycji przewijania.

Arnaud Meuret
źródło
0

Ten link działa dla mnie w wersji demonstracyjnej

1. Załaduj wtyczkę jQuery loadScroll po bibliotece jQuery, ale przed zamykającym tagiem body.

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

2. Dodaj obrazy do swojej strony internetowej za pomocą atrybutu data-src HTML5. Możesz również wstawiać symbole zastępcze, używając zwykłego atrybutu src img.

<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. Wywołaj wtyczkę na tagach img i określ czas trwania efektu zanikania, gdy obrazy są widoczne

$('img').loadScroll(500); // in ms
vebs
źródło
0

Używam jQuery Lazy . Testowanie zajęło mi około 10 minut i godzinę lub dwie, aby dodać większość linków do obrazów na jednej z moich witryn internetowych ( CollegeCarePackages.com ). Nie mam żadnego związku z deweloperem (brak / zero) , ale zaoszczędziło mi to dużo czasu i zasadniczo pomogło poprawić nasz współczynnik odrzuceń dla użytkowników mobilnych i doceniam to.

Cliff Ribaudo
źródło