97

I've noticed this in numerous "modern" websites (e.g. facebook and google image search) where the images below the fold load only when user scrolls down the page enough to bring them inside the visible viewport region (upon view source, the page shows X number of <img> tags but they are not fetched from the server straight away). What is this technique called, how does it work and in how many browsers does it work. And is there a jQuery plugin that can achieve this behavior with minimum coding.

Edit

Bonus: can someone explain if there is a "onScrolledIntoView" or similar event for HTML elements. If not, how do these plugins work?

Salman A
  • 229,425
  • 77
  • 398
  • 489
  • Do you need only image lazy loading ? If you need content lazy loading, infinite scroll plugin is the right answer – soju Feb 25 '11 at 13:19
  • @rsp @jwegner @Nicholas am sorry, but that is not what Salman is asking. – Alec Smart Feb 25 '11 at 13:20
  • @soju: I am only interested in lazy loading images; but I may look at other possibilities sometime in the (fairly distant) future. – Salman A Feb 25 '11 at 13:39
  • 21
    Makes you wonder why a browser's default behaviour isn't to only load images that are visible. Imagine how much bandwidth might have been saved in the last 18 years if that was the case! – Matthew Lock Apr 16 '12 at 02:52
  • Similar question: http://stackoverflow.com/questions/1736215/make-images-load-when-they-enter-visible-section-of-browser – Aaron Digulla Aug 15 '12 at 14:40
  • 2
    While I understand the reason behind lazy loading... I honestly can't stand it when I visit a site that utilizes that method. The blinking of the images drives me nuts! :) – Booski Feb 16 '13 at 23:59
  • @MatthewLock Because it would require all web developers to code their site with this in mind -- if they didn't, the layout of the page would jump and change as the user scrolled down. It would be great if that was the case, but I can't see it becoming standard any time soon. – Chuck Le Butt Apr 29 '15 at 11:39

8 Answers8

65

Some of the answers here are for infinite page. What Salman is asking is lazy loading of images.

Plugin

Demo

EDIT: How do these plugins work?

This is a simplified explanation:

  1. Find window size and find the position of all images and their sizes
  2. If the image is not within the window size, replace it with a placeholder of same size
  3. When user scrolls down, and position of image < scroll + window height, the image is loaded
Blu
  • 3,836
  • 6
  • 33
  • 61
Alec Smart
  • 85,672
  • 35
  • 115
  • 178
  • In application, wouldn't they work the same? An infinite scroll on a single column of images would be the same as lazy loading them, right? Perhaps I'm confused. – jwegner Feb 25 '11 at 20:24
  • 1
    @jwegner Infinite scroll would let you add new items to the bottom of the page when the user reached (or approached) the bottom. Lazy-loaded images could have placeholders of the same dimensions on the page, with the images themselves loaded on scroll. So, the latter could lazy load without affecting the page layout. – Annika Backstrom Feb 26 '11 at 01:29
  • This is working fine on desktop browsers and iOS but doesn't work on android (including 3.x/4.x). Any idea why? is the scroll event not supported? – lahsrah Jan 06 '12 at 01:12
  • I was going through the documentation for this plugin and it seems to be pretty awesome. Going to use this on my next project. – The Muffin Man Sep 30 '12 at 06:32
  • 1
    here's a related plugin, which probably works about the same way: http://afarkas.github.io/lazysizes/ except I believe it's much more robust and uses more of what's already there (no need for placeholder, for instance, but you can have it if you want). – cregox May 28 '15 at 17:19
  • Works well with datatables, until you sort a column, then it stops working. :( – Wonko the Sane Jan 15 '16 at 12:17
  • I know this is a bit old question to comment on but to "load" the image is replacing `src` attribute instead of a placeholder is enough? – Kaung Myat Lwin Oct 03 '17 at 10:50
  • Will this help my page load faster if I'm using several images in one page? Or the images are loaded at the beginning anyway and just being shown while scrolling? – sisorken Dec 02 '19 at 02:55
11

I came up with my own basic method which seems to work fine (so far). There's probably a dozen things some of the popular scripts address that I haven't thought of.

Note - This solution is fast and easy to implement but of course not great for performance. Definitely look into the new Intersection Observer as mentioned by Apoorv and explained by developers.google if performance is an issue.

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

Sample html code

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

Explained

When the page is scrolled each image on the page is checked..

$(this).attr('data-src') - if the image has the attribute data-src

and how far those images are from the bottom of the window..

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

adjust the + 100 to whatever you like (- 100 for example)

var source = $(this).data('src'); - gets the value of data-src= aka the image url

$(this).attr('src', source); - puts that value into the src=

$(this).removeAttr('data-src'); - removes the data-src attribute (so your browser doesn't waste resources messing with the images that have already loaded)

Adding To Existing Code

To convert your html, in an editor just search and replace src=" with src="" data-src="

Hastig Zusammenstellen
  • 3,744
  • 2
  • 29
  • 42
10

(Edit: replaced broken links with archived copies)

Dave Artz of AOL gave a great talk on optimization at jQuery Conference Boston last year. AOL uses a tool called Sonar for on-demand loading based on scroll position. Check the code for the particulars of how it compares scrollTop (and others) to the element offset to detect if part or all of the element is visible.

jQuery Sonar

Dave talks about Sonar in these slides. Sonar starts on slide 46, while the overall "load on demand" discussion starts on slide 33.

ashleedawg
  • 17,207
  • 5
  • 53
  • 80
Annika Backstrom
  • 13,337
  • 5
  • 38
  • 52
  • I wonder how does this compare to Appelsinii's lazyload? Is it more lightweight? Does it work on every browser? I remember lazyload does not work on Chrome. – deathlock Aug 18 '12 at 21:02
5

There is a pretty nice infinite scroll plugin here

I've never programmed one myself, but I would imagine this is how it works.

  1. An event is bound to the the window scrolling

    $(window).scroll(myInfinteScrollFunction);
    
  2. The called function checks if scroll top is greater than the window size

    function myInfiniteScrollFunction() {  
        if($(window).scrollTop() == $(window).height())  
        makeAjaxRequest();  
    }
    
  3. An AJAX request is made, specifying which result # to start at, how many to grab, and any other parameters necessary for the data pull.

    $.ajax({
        type: "POST",
        url:  "myAjaxFile.php",
        data: {"resultNum": 30, "numPerPage": 50, "query": "interesting%20icons" },
        success: myInfiniteLoadFunction(msg)
    });
    
  4. The ajax returns some (most-likely JSON formatted) content, and passes them into the loadnig function.

Hope that makes sense.

Blu
  • 3,836
  • 6
  • 33
  • 61
jwegner
  • 6,063
  • 8
  • 32
  • 55
3

Lazy loading images by attaching listener to scroll events or by making use of setInterval is highly non-performant as each call to getBoundingClientRect() forces the browser to re-layout the entire page and will introduce considerable jank to your website.

Use Lozad.js (just 569 bytes with no dependencies), which uses IntersectionObserver to lazy load images performantly.

Hastig Zusammenstellen
  • 3,744
  • 2
  • 29
  • 42
Apoorv Saxena
  • 3,736
  • 9
  • 27
  • 44
1

The Swiss Army knife of image lazy loading is YUI's ImageLoader.

Because there is more to this problem than simply watching the scroll position.

Chris Vasselli
  • 11,894
  • 4
  • 42
  • 47
Arnaud Meuret
  • 977
  • 8
  • 24
0

Im using jQuery Lazy. It took me about 10 minutes to test out and an hour or two to add to most of the image links on one of my websites (CollegeCarePackages.com). I have NO (none/zero) relationship of any kind to the dev, but it saved me a lot of time and basically helped improve our bounce rate for mobile users and I appreciate it.

Cliff Ribaudo
  • 8,509
  • 2
  • 50
  • 74
0

This Link work for me demo

1.Load the jQuery loadScroll plugin after jQuery library, but before the closing body tag.

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

2.Add the images into your webpage using Html5 data-src attribute. You can also insert placeholders using the regular img's src attribute.

<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.Call the plugin on the img tags and specify the duration of the fadeIn effect as your images are come into view

$('img').loadScroll(500); // in ms
vebs
  • 297
  • 1
  • 4
  • 10