Most search engines will index images that are hidden as long as you don't use inline styles to hide the image. The majority of browsers will not load hidden images.
There is a test page that can verify this claim. Some older mobile browsers are the exception, but I argue lazy loading on mobile phones could be counter productive to a good browsing experience.
http://www.w3.org/2009/03/image-display-none/test.php
In your CSS file add the following modification.
.lazy-img { display: none; }
Now you can load a page with lazy images like this and they will be indexed.
<body>
<img class="lazy-img" src="img1.jpeg" title="image title"/>
<img class="lazy-img" src="img2.jpeg" title="image title"/>
<img class="lazy-img" src="img3.jpeg" title="image title"/>
<img class="lazy-img" src="img4.jpeg" title="image title"/>
</body>
It's important that you include the title
attribute for the image. Or you surround the <img
> tag with a link <a
> tag and link text. Otherwise search engines will associate keywords with the image by word distance. You're going to all this trouble for SEO you might as well go all the way.
If you use the above as is. Nothing will show as the images are hidden. You want to remove this class at the bottom of the document. The key here is to use inline pure Javascript. This Javascript is executed immediately after layout of the above elements are finished. If you load all your external JS files at the bottom (as you should). You should place this Javascript block above those files. So that there is no lag in modifying the DOM.
<body>
<!--[if lte IE 8]
<style type="text/css">.lazy-img { display: block !important; }</style>
[endif]-->
<noscript><style type="text/css">.lazy-img { display: block !important; }</style></noscript>
<img class="lazy-img" src="img1.jpeg" title="image title"/>
<img class="lazy-img" src="img2.jpeg" title="image title"/>
<img class="lazy-img" src="img3.jpeg" title="image title"/>
<img class="lazy-img" src="img4.jpeg" title="image title"/>
<![if gte IE 9]>
<script type="text/javascript">
var images = document.getElementsByClassName('lazy-img');
Array.prototype.forEach.call(images, function(image){
image.setAttribute("data-src",image.getAttribute("src"));
image.setAttribute("src","loading.gif");
});
while(images.length > 0) { images[0].className = ""; }
</script>
<![endif]>
</body>
Now I added conditionals for IE9 since it doesn't support getElementsByClassName
in 8 and older. What should happen (not tested) is that those browsers will just load the image as is.
The advantage of this approach is it keeps the HTML looking clean from the perspective of the webcrawler.