Faster page loads with image lazy loading

by Jeba Singh Emmanuel on March 14, 2011

in Performance,User Experience

Almost all traffic on slideshare goes to one type of page: the “view” page (the page where a document is displayed). As a result, we spend a lot of energy trying to tune the code that generates that page. Any decrease in page load time that we can get directly improves the user experience for all our users. Recently we were able to make big improvements by changing the way images load. This blog post will describe how we did it.

A large percentage of our page load time is taken up by images downloading. We’d already done a lot of work to reduce this (for example, by setting far-futures expires on many images, and by spriting images together to reduce the number of images downloaded). But the unique images for document thumbnails and profile pictures was not spritable, and far-future-expiry was unlikely to have much impact (since the images are usually unique to a given document). What to do?

After thinking about it a while, we realized that many of these profile and thumbnail images are below the fold in our current design, and therefore don’t need to be included in the initial pageload. Postponing loading of these images sped up the page a lot. By loading these images only when the user scrolls to those locations, we can avoid loading of these images unless the user is viewing them, saving a lot of bandwidth and speeding up the page quite a bit. This technique is called image lazyloading.

We implemented this on slideshare in february and noticed marked improvement in performance.
On one of our monitoring endpoints for a popular page

Average Size Images
Before Lazy load 497kb 1702
After Lazy load 445kb 942

On another of our endpoints for another page

Load Time Requests Bytes in
Before Lazy load 24.9s 123 2310kb
After Lazy load 13.2s 85 787kb

To implement lazy load, we have used the jQuery lazy load plugin.

So without much ado, here is the code.

<script type="text/javascript">
ss = <%= {:userPlaceholder => User::PLACEHOLDER_IMAGE}.to_json %>
</script>
 
<ul>
<% comments.each do |comment| %>
 <li class="j-lazyload-comment comment">
   <span class="userSummary">
      <img src="<%= User::PLACEHOLDER_IMAGE %>" original-src="<%= comment.user.image %>"/>
      <%= comment.user.summary %>
   </span>
   <span class="commentText"><%= h(comment.displayText) %>
 </li>
<% end %>
</ul>

The above section of the rails view generates the list of comments for the slideshow. Notice that we are populating the src attribute of the image tags with a placeholder image and setting a custom attribute ‘original-src’ with the actual image. This is resource url that the jQuery lazy load plugin will use.

And the javascript for the lazy load is

$(function(){
 $("li.j-lazyload-comment img").lazyload({
   effect: 'fadeIn', 
   placeholder: ss.userimage_placeholder
 });
});

For the related slideshows section which has a list of thumbnails scrollable in a container, we use the following code

$(function(){
 $("li.j-lazyload-related img").lazyload({
   effect: 'fadeIn', 
   placeholder: ss.slideshow_placeholder, 
   container : '#relatedList'
 });
});

As you see, it is quite easy to set up and get running. You could use the noscript tag to avoid lazyload and show the actual images for users who have javascript disabled. If you want more control over the behavior that what this plugin provides, you may be interested in waypoints.

I hope this post will help you make your website faster. Please let me know what you think of it in the comments section below. If making big web sites faster is the kind of thing you like doing, you should know that we’re hiring.

Jeba Singh Emmanuel
Senior Software Engineer

{ 15 comments }

Bedupako March 17, 2011 at 5:50 pm

i am implimenting first thing in the morning in the website… thanks a lot! i didnt know of the jQuery thing

Shirsendu March 18, 2011 at 4:29 am

Really simple yet so much useful.

Abhishek March 18, 2011 at 5:00 am

can you confirm that the images ACTUALLY load ‘lazily’. I think the images load as usual(as shown in the firebug NET console)

Mariusz March 20, 2011 at 9:52 am

Very elegant implementation of lazy load. Your users (incl. me) are be very thankful for fast responsiveness of slideshare’s websites.
(nb: see my presentation with many tips and tools for performance improvement http://www.slideshare.net/bonoseo/web-performance-optimization-wpo )

Would be very interested in some statistics of how this implementation imroved bounce rate and overall page views.
@hiring: Working for you might be great.. but difficult from Europe ;)

Thanks for sharing guys :)

crmamx March 20, 2011 at 1:10 pm

A lot of favorable comments from the “pros” on different forums. But what about us novices? Any chance you could be more detailed in how and where to install the different sections of code for us?

Thanks

Nikhil Kulkarni March 20, 2011 at 3:04 pm

The Lazy Load website says it nor more works with major browsers … are you still using Lazy load ?

Thomas Vervik March 21, 2011 at 9:32 am

On the homepage of the plugin there is a warning div:

http://www.appelsiini.net/projects/lazyload

“Lazy Load is currently not usable. It does not work with the latest browsers as expected. I have currently no time updating the code myself. Patches are always welcome. If you find a solution just fork and send a pull request. Thanks!”

I got a bit afraid using it with this warning, suddenly ending up after a lot of work with some code which doesnt work in all browser enviroments. Did you experience any trouble with it?

Gaurish Sharma March 21, 2011 at 5:38 pm

Hey Jeba,
precise, accurate and to the point. Finally you are getting the audience that you might not have gotten at your blog. Good work buddy ;)

Ankur Jain March 21, 2011 at 6:41 pm

Came here through your newsletter. It’s the first time I heard of image lazy loading. I would be interested in answers for Nikhil’s and Thomas’ questions above.

Jeba Singh Emmanuel March 22, 2011 at 7:26 am

@abhishek – Can you specify browser and OS versions? You need to set the src to the placeholder in your markup and set original-src to the image you want to lazy load. The newer browsers load the images immediately, so you should see the placeholders being loaded, not the actual images.
@nikhil and @thomas – see reply to @abhishek, also http://www.appelsiini.net/2009/12/tuning-lazy-loader.

koolhead17 March 23, 2011 at 7:39 am

Nice jeba.
Good to see your blog after ages!!
Keep more coming!!

Goodluck!!

Atul

online muslim matrimonials March 28, 2011 at 9:39 am

Nice way to guide how to increase the page loading speed.

Mike L April 5, 2011 at 2:45 pm

Thanks for the article. Any word on how switching out the SRC affects Google Image search indexing? Really wonder how this affects SEO…

Larry A May 20, 2011 at 7:52 am

Regarding your first code sample, I can only give you the advice to learn how to use taglibs and JSTL. Your Java scribbles make your code horribly hard to read and the approach goes against any idea of proper MVC-design. (What you are doing with your code is actually to merge model details straight into your view.)

My second comment is regarding the jQuery lazy-load-plugin. It uses to the load function and other bits that are implemented differently in different browsers and which basically means non-existent cross-browser support (something which you can read in the very first and very red section of the plugin page).

Anybody really thinking about cross-browser support should be VERY careful with your advice.

Best regards,

Larry

موقع مسيحي دوت كوم May 24, 2011 at 11:36 pm

Thanks for sharing
Is there a way to load page content like Javascripts, images, and other after the onload event?

Thanks,

Comments on this entry are closed.

{ 4 trackbacks }

Next post: