Overview
What is lazierLoad
?
lazierLoad
is Bramus! his take at writing a delayed javascript image loader for use with PrototypeJS.
lazierLoad
automatically hooks itself to the page, finds all images and only loads those appearing “above the fold” resulting in faster page loads. The images not located in the viewport, are not loaded until they appear within it (viz. when the user scrolls down).
The idea for lazierLoad
was inspired upon Lazy Load (which is built for use with jQuery), yet the code differs quite a lot.
Demo
(Pictures by Pieter Morlion)
Download
Please download the latest version below:
Latest Version
Archived Versions
Don’t forget to read the License & usage and Installation/Configuration blocks on this page! 😉
Version History
Version 0.4 – 2008.02.28
- ADD: ability to automatically autoLoad or not
- UPD: backdrop from 0.2 where one could set options through a new instantiation, enabling one to have per page options
Version 0.3 – 2008.02.26
- ADD: options: minWidth, minHeight, imgTypes
- UPD: moved all options to global Object
- UPD: works with latest Prototype (1.6.0.2)
Version 0.2 – 2007.09.12
- ADD: options: treshold, loadingImage, replaceImage
Version 0.1 – 2007.09.11 – * INITIAL RELEASE *
- Well … first release.
License & usage
The script is now released under a creative commons Attribution-ShareAlike 2.5 license. Should you use the script within a commercial context please think about clicking the PayPal donate button.
Installation/Configuration
Installation
lazierLoad
depends on PrototypeJS 1.6.0 Final or greater (1.6.0 beta or rc won’t work!). Prototype 1.6.0.2 is included in the release 😉
-
Include the needed javascript (2 files) in your HTML document
<!-- lazierLoad prerequisites : prototype.js - version 1.6.0 final or greater required! --> <script type="text/javascript" src="js/lib/prototype.js"></script> <!-- lazierLoad core --> <script type="text/javascript" src="js/bramus/lazierLoad.js"></script>
- That’s it, you’re done!
Configuration
Automatic hooking of lazierLoad – Configuring the default options
If you are not happy with the default settings, you can tweak lazierLoad
by editing the lazierLoadDefaultOptions
Object in the lazierLoad.js
file.
Possible options to tweak are:
treshold
: images which appear treshold pixels from the bottom will be loaded
(defaults to100
)replaceImage
: image to replace the non-loaded images with until they are loaded (most likely a transparent 1 by 1 pixel image)
(defaults to"blank.gif"
)loadingImage
: image to show while a non-loaded image is being loaded
(defaults to"spinner.gif"
)extensions
: array of extensions to lazyLoad
(defaults to['gif','jpg','png','jpg']
)minWidth
: minimum width an image must have in order to be lazyLoaded
(defaults to100
)minHeight
: minimum height an image must have in order to be lazyLoaded
(defaults to100
)
Manual hooking of lazierLoad – Configuring page-specific options
If you want different options on different pages, then set lazierLoadAutoHook
to false
and manually create a new JS_BRAMUS.lazierLoad
instance yourself. Within that manual instantiation you can pass in specific parameters. If set, these parameters will override the default parameters set in the lazierLoadDefaultOptions
Object.
Some examples are (only include one instantiation per page though!):
Event.observe(document, 'dom:loaded', function() {
myCustomLL = new JS_BRAMUS.lazierLoad({treshold: 200}); // Override treshold
}, false);
Event.observe(document, 'dom:loaded', function() {
myCustomLL = new JS_BRAMUS.lazierLoad({loadingImage: 'bigspinner.gif', minWidth : 200, minHeight; 200}); // Override spinner, minWidth and minHeight
}, false);
Event.observe(document, 'dom:loaded', function() {
myCustomLL = new JS_BRAMUS.lazierLoad({extensions: ['png','jpg']}); // Override extensions : Only JPG's and PNG's
}, false);
Event.observe(document, 'dom:loaded', function() {
myCustomLL = new JS_BRAMUS.lazierLoad({treshold : 150, extensions : ['png','jpg','jpeg'], replaceImage : "blank.gif", loadingImage : "bigspinner.gif", minWidth : 200, minHeight : 200}); // Override all options.
}, false);
Current Limitations
- Lazy loading does not currently work with safari because of webkit bug #6656 (same goes for Lazy Load).
Feedback/Help/Support
One can always leave a comment in case any questions should arise or if a bug were to be found; and one can always support me by donating me a tidbit to my paypal
Make a donation
It certainly is no obligation but it would most certainly put a smile on my face 😉 Alternatively you can support me by clicking one of the ads below.
Any idea why lazierLoad breaks google analytics?
I get this error in firebug
“urchinTracker is not defined”
_uacct = “myIDHere”;
urchinTracker();
sorry my last script code got removed…
script src=”http://www.google-analytics.com/urchin.js” type=”text/javascript”
/script
script type=”text/javascript”
_uacct = “UA-423341-1”;
urchinTracker();
/script
@Ryan: that’s an error you receive if
http://www.google-analytics.com/urchin.js
isn’t loaded properly.Let me guarantee you that it forks fine with Google Analytics as the demo page has GA implemented (lines #97 up to #103) 😉
Thanks for the code, it works great. I have implmemneted it in my Lazy Big Web Gallery.
It’s working very nice with Prototype JavaScript framework, version 1.6.0_rc0 but NOT with Prototype JavaScript framework, version 1.6.0.
Don’t know why, I just tested it!
@Boyan: will take a look into it. Thanks for mentioning!
well, your script apparently shares a common problem with the YUI and jquery versions: when i jump to the end of the page then *all* images get loaded.
it would be better if loading was only triggered for images that have been in the viewport for, say, 1.5 seconds.
@moe: that’s because the images at the very top (not onscreen though) are “above the fold” and thus should be loaded. To make things more clear: the script loads images “above the fold”; not images “in the viewport” 😉
Hiya!
Bramus, i was successful in installing and using your code on my website – honestly I’ve been looking for this forever. I have alot of images usually on one page and some of the javascript waits for the page to completely load so the images often cripple accessibility – All Fixed Now!
I can echo ‘Boyan Boychev’ on it not working with the non-beta version of prototype – I was not even able to use it with the compressed version of your own included prototype.js.. i guess that’s not a major problem since i have both gzip and minify active on my page..
You are a life saver with your code – i’ll be making some personal adjustments, but maybe you would like to hear them?
I would love if this could have a minimal image dimension check (before replacing the loader image), so it doesn’t try to fit a larger image in a smaller one.. I’m adding a width & height > ~ 200 px .. maybe an extension check? png and jpg only (?)
bc of this bug on my page (i don’t know why it happens)
http://pictor.us/journal/page/2/ (not a permalink)
but the loader image stays under the two images i have on the sidebar .. loacated at the header “Journal is Powered By”
they are both transparent themselves – so i guess… your script doesn’t remove the loader image after its done? (I’ll look into that too – but i’m not much a coder hehe)
So fabulous, i’ll bookmark this, and check later 🙂
just to add that maybe it wouldn’t be bad if it was mentioned that the script needs the image element to have both width and height defined for it too have the ajax loader visible.
(is there a way around this btw? I can’t think of one .. script can’t call an image’s dimensions without loading the image can it?)
update:
it was really easy to implement the minHeight and minWidth options.. but i’m having trouble on the file type check..
my code:
this.element.fileName = this.element.origSrc.substring(imgPath.lastIndexOf('/')+1,this.element.origSrc.length);
this.element.fileType = this.element.fileName.substring(imgPath.lastIndexOf('.')+1,this.element.fileName.length);
Then comparing this to ‘jpg’ OR ‘png’
not really working..
🙂 any help appreciated !!!
@mo: This here works (note that I’m takeing the
lastIndexOf
thethis.element.fileName
instead of theimgPath
) 😉this.element.fileName = this.element.origSrc.substring(this.element.origSrc.lastIndexOf('/')+1,this.element.origSrc.length);
this.element.fileType = this.element.fileName.substring(this.element.fileName.lastIndexOf('.')+1, this.element.fileName.length);
@mo: couldn’t help myself and quickly implemented the changes you mentioned in 0.3 😉
wbr,
B!
Hi Bramus,
oh, that’s just wonderful :]
makes me very happy!
I tested it and it works like a charm 🙂
maybe the readers would like to know that Ver 0.3 also works with the packed version of prototype (47kb) now. Downloadable here.
I wasn’t able to find out how one can set variables outside the js file, ie. if one wants to set the threshold per page, how does one write it?
Thanks for everything!
@mo: … and *bam*, 0.4 has arrived 🙂
so fast!
thank you.. and all these changes.
it looks beautiful though, i don’t see anything else here left to desire :]
Wonderful work Bramus!
any word on IE support? (alteast 7.0?) … I know its a shit browser but I would still love to have it work ..
I’m guessing it has something to do with ie’s poor implementaiton of img.onload?
Hey Bramus,
First,I wanted to point out that lazierLoad is AMAZING, it’s really a major boost to my website.Thanks!
Second ,I was wondering if there an option to attach the lazierLoad behavior to images loaded and attached to the DOM after page load?
I retrieve using ajax some more images to display which are appended to the bottom of the page while scrolling down. I’d like that the threshold of the ajax request will be higher than the lazierLoad one.
Is there similar dom:loaded event for changes made dynamically to the DOM?
Thanks in advance,
Aviel.
@dmose: should work fine …
@Aviel: Don’t know of any dom:changed event. What you could do is manually instantiate
new JS_BRAMUS.lazierLoadImage(image, options);
whereimage
is $(‘id_of_the_image_you_just_inserted’) andoptions
can be null (the script will fallback to the default options) or an object as described in the configuration part.It is nice. However it doesnt work if the image link like http://someone.com/thumbs/image=23123.jpg
Do you know how ?
Thanks
Hello,
While testing lazierLoad noticed that it stops proper detection of images positions after resizing browser window. The solution is in my opinion to add window resize event handler.
Regards,
Artur
@Mic: Should work, as the “jpg” extension is in the allowed extensions list. Sure it’s wrapped in an img tag? Sure you’re not using Safari (@see? Any demo page you can provide?
@Artur: great find indeed. Didn’t implement that (yet). Pushing it on my (ever growing) todo list.
Looks great and lite, but I’m having trouble configuring it for dynamic images. They are .rbx files with arguments. For example:
thumb.rbx?size=1&image=//images/AmeCon2008/dscf2336.jpg#1
I’ve added rbx as a extension, so I’m wondering if I need to strip off everything after the ? character.
Any recommendations?
so — i don’t get it. is the idea behind the lazy load technique to stop the download of non-visible images and speed up the download process as a whole? right? it’s not just a superficial thing about fading them up as you scroll is it?
i imagine that’s supposed to be the point? download the images as they come into view, so that you aren’t choking your internect connection by loading things you can’t see to begin with.
the problem is — that doesn’t happen with this script (or any that i can tell). if you look at firebug, or safari’s activity monitor, all the images get downloaded anyway. it seems like they are just downloading twice? once on DOM load, and again as they come into view.
am i missing something?
Hmm, well, im trying it out with 1.6.0.4 and it doesn’t seem to work, tried it with the one that comes in there and it doesnt seem to work either, weird. Do the images have to be in the same directory as the js rather than in my images folder?
It doesn’t work when I put another jquery file in one page, say a tooltip plugin and a zoom in image plugin.
First of all, great work. I am going to use it on my website redesign. One question:
Is one able to configure fadein effect like LazyLoad’s?:
http://www.appelsiini.net/projects/lazyload/enabled_fadein.html
I would love for the loaded images to fade in. Thanks!
I’m going to agree with michael sablone, this script still downloads the images on initial load so this doesn’t have any effect on improving page load time….
is it possible to make it work in PrototypeJS 1.5.0 ?
this one work only for PrototypeJS 1.6.0 and up.
perhaps a few changes could make it work with PrototypeJS 1.5.0 ? that’s what i’d really love
Hi,
I was trying to use the lazy loader library you created and noticed a bug.
I have some small images, smaller than the loading wheel, and when those are loaded, the wheel keeps turning behind it, as a background. I notice using Firebug that this happens for your images as well, however they are big and are covering the loading gif.
If you need more info about the error, just contact me!
Thanks!
Hi,
Looking at your demo page, and the code I noticed that your script not only doesnt do the “lazy loading”, meaning downloading the image as you reach it with Viewport, but it downloads the images 2 times! multiplying the bandwidth.
you can see it in firebug.
first time the images loaded in the tag
then the script downloads the images second time.
It appears that the lazy loading feature no longer works. Using Fiddler you can see all the images load without scrolling the page
fix for removing spinner image after loading original image from cache/server
**This will happen only for transparent image**
After successfully loading of original image you have to remove spinner , for this you have to add below line in image loading completion code in lazyScroll function
this.element.style.backgroundImage = null;
This was cool – but after browser updates it no longer works.
Its really unfortunate that lazy loading is no longer working in any browsers. If anyone figures out a good solutions please email me at thawkes@woodstitch.com.
I think this big problem that needs fixing.