11

I am developing an eshop .At products page based on category i putted some javascript based filtering. However a problem arises if a category has a lot of products. This link has something similar i do ... http://www.snowandrock.com/sunglasses/snowboard/fcp-category/list?resetFilters=true

How ever this page is painfully slow and is over 2mb !!!

Every product for me needs half killobyte but the image is the problem.. So i am looking how to lazy load images.. Since my page has pagination unlike that site i think that loading images that are visible only to the page is a solution.The probem however is how to do it in order to work both for javascript and non javscript enabled people.. The only solution i though is storing the link at the css class somehow of the image for the non visible products and if shown after filtering change via javascript the image src... Non javascript users dont have this problem as clicking on a filter would navigate them to other page...

Any other idea?

GorillaApe
  • 3,611
  • 10
  • 63
  • 106
  • 2
    Do pagination on the **server-side**. If you only load 20 images at once it should't be slow. – gblazex Oct 27 '10 at 14:05

7 Answers7

7

Four options:

Here are three options for you:

Use a background image

Kangkan's background answer has this covered.

If that doesn't work for you, I'm assuming you only need help with the JavaScript-enabled stuff, since you said the non-JavaScript users will see a different page.

Use a plug-in

Paging has been done. You've said in a comment that you're using jQuery. There are lots of jQuery plug-ins for paging. Find one you like, and use it. They will be of varying quality, so you'll want to test them out and review their code, but I'm sure there's a decent-quality one out there.

Server-side Paging

This is where the main page loads either without any products at all, or with only the first page of products. Typically you'd put all of the products into a container, like this:

<ul id='productList'>
</ul>

Then you'd have the usual UI controls for moving amongst the pages of results. You'd have a server-side resource that returned HTML snippets or JSON-formatted data that you could use to populate that list. I'll use HTML for simplicity (although I'd probably use JSON in a production app, as it would tend to be smaller). Each product entry is its own self-contained block:

<li id='product-001'>
  <div>This is Product 001</div>
  <img src='http://www.gravatar.com/avatar/88ca83ed97a129596d6e8dd86deef994?s=32&d=identicon&r=PG'>
  <div>Blurb about Product 001</div>
</li>

...and then the page returns as many of these as you think is appropriate. You request the page using Ajax and update the product list using JavaScript. Since you've said you use jQuery, this can be be trivially simple:

$('#productList').load("/path/to/paging/page?start=X&count=Y");

Here's an example prototype (not production code); it fakes the Ajax because JSBin was giving me Ajax issues.

One big page download, then client-side JavaScript paging

I'm not sure how you're doing your filtering, but if you have an element that contains the product information, you can store the image URL in a data-xyz attribute on it:

<div id='product-123' data-image='/images/foo.png'>

Then when your code makes that visible, you can easily add an img to it:

var prod, imgsrc, img;
prod = document.getElementById('product-123');
prod.style.display = 'block'; // Or whatever you're doing to show it
imgsrc = prod.getAttribute('data-image');
if (imgsrc) {
    img = document.createElement('img');
    img.src = imgsrc;
    prod.appendChild(img); // You'd probably put this somewhere else, but you get the idea
    prod.removeAttribute('data-image');
}

Edit In a comment elsewhere you said you're using jQuery. If so, a translation of the above might look like this:

var prod, imgsrc, img;
prod = $('#product-123');
prod.show();
imgsrc = prod.attr('data-image');
if (imgsrc) {
    $("<img/>").attr('src', imgsrc).appendTo(prod); // You'd probably put this somewhere else, but you get the idea
    prod.removeAttr('data-image');
}

No need to remove it again when hiding, since the image will already be shown, which is why I remove the attribute once we've used it.

The reason I've used the data- prefix is validation: As of HTML5, you can define your owwn data-xyz attributes and your pages will still pass validation. In earlier versions of HTML, you were not allowed to define your own attributes (although in practice no major browser cares) and so if you used your own attribute for this, the page wouldn't validate.

References (w3.org):

Off-topic, but a lot of this stuff gets a lot easier if you use a JavaScript library like jQuery, Closure, Prototype, YUI, or any of several others to smooth over the rough edges for you. (You've since said you're using jQuery.)

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • data-attribute validates or not ? Is there a way to make it validate? – GorillaApe Oct 27 '10 at 13:34
  • @Parhs: I talk about validation in my answer. If you declare the document as HTML5 (` `), yes, it will validate. If you don't, it won't. It doesn't *matter* unless validation is a big part of your working practice (which it should be), because even if you don't use the HTML5 declaration, all major browsers allow custom attributes. That said, despite some stoopid comments from HTML5 Working Group members, [I'm with John Resig](http://ejohn.org/blog/html5-doctype/): No reason not to use the HTML5 doctype *right now*. – T.J. Crowder Oct 27 '10 at 13:38
  • I was wondering if using HTML5 doctype would trigger quirks mode in ie6 etc.. That would be BAD – GorillaApe Oct 27 '10 at 19:35
  • Actually i get problems setting this doctype.. I get under the images some kind of invisible margin-padding – GorillaApe Oct 27 '10 at 20:01
  • @Parhs: *"I was wondering if using HTML5 doctype would trigger quirks mode in ie6 etc.."* No, just about any `DOCTYPE` tells the browser to go into standards mode: HTML5: http://jsbin.com/uligo3 HTML4: http://jsbin.com/uligo3/2 Quirks: http://jsbin.com/uligo3/3 – T.J. Crowder Oct 28 '10 at 06:13
  • @Parhs: *"I get under the images some kind of invisible margin-padding"* It should be easy enough to use development tools (the Dev Tools built into Chrome or Safari, Firebug for Firefox, the free VS.Net for IE) to see the exact computed style of the elements and adjust your CSS accordingly. One of the big things that standards mode does is rationalize some CSS behavior, particularly IE's broken box model. More reading: http://en.wikipedia.org/wiki/Quirks_mode | http://www.alistapart.com/articles/doctype/ | http://hsivonen.iki.fi/doctype/ – T.J. Crowder Oct 28 '10 at 06:22
  • @Crowder: A great post looking at all possibilities. Thanks. – Kangkan Oct 28 '10 at 08:04
  • http://stackoverflow.com/questions/4026994/improve-performance-of-this-jquery-script-closed Here is how i implement filtering.. thank for all the details! i would go with the last approach.. Because images should be resized background images isnt a solution for products... – GorillaApe Oct 28 '10 at 09:46
4

If you simply wish to load the images slowly and the rest of the page gets loaded first, you can put the images as background and not use the <img> tag. If you use the <img> tag, the image is loaded at the time of loading the page and so the page load becomes slow. However, the background images loads after the page is shown to the user. The user can read the text and see the images loading after some time.

Kangkan
  • 15,267
  • 10
  • 70
  • 113
  • this is the behaviour for all browsers? If it is hidden its not visible you mean? – GorillaApe Oct 27 '10 at 13:31
  • @Parhs: This is the behaviour in all major browsers, I have checked. But probably we need to check it if it is the standard. Also, if sometimes, the loading actually fails due to very long time of loading. It is a known problem when you have big images. But with lots of small images (like in the case of a catalogue), it generally works. – Kangkan Oct 27 '10 at 13:59
  • Which browsers did you check this? Any source for this knowledge? thanks it's a good thing to know. – Adriano Jun 25 '14 at 11:17
  • @AdrienBe: This is what I have observed long back. This might have changed with modern browsers and better connectivity. But for some site, I got good result doing this. – Kangkan Jun 26 '14 at 07:11
  • 1
    5+ years later, this doesn't seem to work any more. (Chrome anyway) – Chris Fremgen May 06 '16 at 18:26
1

I'd suggest to implement responsive image approach in order to avoid huge image files on devices which cannot display it properly (or human can't tell the difference).

Pavel Podlipensky
  • 8,201
  • 5
  • 42
  • 53
1

I wrote the following code for my own site. I used JQuery: 1. Name all classes, where U want lazy loading by the same name, say "async" 2. Copy the real image location from 'src' to 'alt' attribute 3. After finishing page loading my script will copy all 'alt' values into 'src' Look at example. This is full working sample html:

<html> 
<head> 
<script src="http://code.jquery.com/jquery-1.9.1.js"></script> 
<script type="text/javascript">
        $(document).ready(function(){
            $('img.async').each(function(i, ele) {
                 $(ele).attr('src',$(ele).attr('alt'));
            });
        });
        </script> </head> <body> <img class="async" title="Гороскопы" alt="http://virtual-doctor.net/images/horoscopes.jpg" width="135" height="135"/> 
</body>
</html>

You can feel the speed in real site, where I used it http://virtual-doctor.net/

Jeff_Alieffson
  • 2,672
  • 29
  • 34
1

I'm fairly certain it's not possible in plain HTML without some kind of Javascript intervention.

After all, if it was possible to do it without scriping, why would anyone have implemented it in Javascript in the first place?

My question is: How many visitors do you get who these days don't have Javascript enabled? I bet it's very few. And in any case, those people are used to sites not being fully functional when they have javascript disabled; your site will actually be better than most if the only difference they have to put up with is slower loading speed.

(ps - I presume you're using Jquery's LazyLoad plugin for the Javascript enabled people?)

Spudley
  • 166,037
  • 39
  • 233
  • 307
  • 2
    *"I presume you're using Jquery's LazyLoad plugin for the Javascript enabled people?"* He hasn't said he's using jQuery. jQuery != JavaScript !! ;-) – T.J. Crowder Oct 27 '10 at 13:33
  • i am using Jquery but havent done anything yet for the issue i describe – GorillaApe Oct 27 '10 at 13:37
  • @TJ: Yes I know JQuery != JS. ;) I was guessing he was already using that plug in since he used its name in the question. (and I provided the link in case he wasn't and in case it would be useful) – Spudley Oct 27 '10 at 13:49
1

Browser level support

Modern browsers have the ability to load images lazy using loading="lazy" attribute!

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

For more information, visit here.

Amir Fo
  • 5,163
  • 1
  • 43
  • 51
0

EDIT: I reread your question & noticed you also want this to work for people with Javascript disabled! Then yes my answer is not acceptable - but I'll leave it for the record.

Here are some Javascript libraries for Image Lazy Loading.

They help you load the images needed when the elements 'would' be in view by simply changing the image src attribute.

Important: I am still investigating which of these Javascript libraries is best to use. Do your homework I'd say, take some time to search what's the best tool for the job. My requirements are usually: license, dependencies, browser support, device support, weight, community, and history.

Adriano
  • 19,463
  • 19
  • 103
  • 140