+ The ImageLoader Utility allows you as an implementer to delay the loading of images on your web page until + such a time as your user is likely to see them. This can improve your overall pageload performance by deferring + the loading of some images that are not immediately visible at the time the page first renders. + Because images are often the heaviest components of a given page, deferring the loading of some images can + yield a marked improvement in the way the page "feels" to your user. +
+ ++ The ImageLoader Utility lets you determine triggers and time limits to initiate image loading. + This allows you to ensure that the images are loaded before your user is likely to see them. + This technique, obviously, is appropriate only for images that are not immediately visible to your user at initial page load. +
+Getting Started
+ ++To include the source files for ImageLoader and its dependencies, first load +the YUI seed file if you haven't already loaded it. +
+ +<script src="http://yui.yahooapis.com/3.10.3/build/yui/yui-min.js"></script>+ + +
+Next, create a new YUI instance for your application and populate it with the
+modules you need by specifying them as arguments to the YUI().use() method.
+YUI will automatically load any dependencies required by the modules you
+specify.
+
<script>
+// Create a new YUI instance and populate it with the required modules.
+YUI().use('imageloader', function (Y) {
+ // ImageLoader is available and ready for use. Add implementation
+ // code here.
+});
+</script>
+
+
+
+For more information on creating YUI instances and on the
+use() method, see the
+documentation for the YUI Global Object.
+
Creating an Image Group
+
+ Images are organized into groups. Each group has one or more triggers. A trigger is simply any DOM event,
+ such as the mouseover of a specific <div>, a button click, or a window scroll.
+ The images in a group won't load into the page until this trigger fires. Groups also have an optional time limit;
+ if none of the group's triggers are activated before the time limit expires, the images are fetched anyway.
+
+ A group is defined as an instance of Y.ImgLoadGroup. It comprises a collection of images that will
+ show up on the page based on the same triggers and time limit.
+
+
var myFirstGroup = new Y.ImgLoadGroup({ timeLimit: 2 });
+myFirstGroup.addTrigger('#someDivId', 'mouseover');
+
+
+
+ This defines a group triggered by a mouseover of the <div> with the HTML ID
+ of someDivId; with the timeLimit attribute we are specifying that all images
+ in myFirstGroup should load two seconds after the window's load event fires even
+ if our trigger hasn't been tripped.
+
Adding Images to the Group
++ Register one or more images with the group using the HTML ID of the image element and the URL for the image: + +
myFirstGroup.registerImage({
+ domId: 'idOfDivWaitingForImage',
+ bgUrl: 'http://www.example.com/image/url'
+});
+
+
+
+ This will set the image at http://www.example.com/image/url as the background image of
+ the <div> with the ID idOfDivWaitingForImage. There are three kinds of images you
+ can register with an ImageLoader group instance; see Adding Images below for more details on this process.
+
Using the ImageLoader Utility
++ This section describes how to use the ImageLoader Utility in further detail. It contains these subsections: +
+-
+
- Performance Considerations +
- Approach +
- Triggers +
- Custom Event Triggers +
- Adding Images +
- Loading Images Below the Fold +
- Image Visibility +
- Using Class Names +
Performance Considerations
+
+ The images on your page require possible DNS lookups, new HTTP transactions, and ultimately the transmission
+ of image data in packets over the wire. While all this is happening, the user is often left waiting for the
+ page to become fully functional. All of your onload JavaScript, for example, is deferred until
+ after all the page's images have finished loading.
+
+ Should the user have to wait for all of these images? If the images are front and center on the page, then yes, + suffering the load time is necessary. But what about images that the user doesn't see right away — the images + below the fold; the images hidden towards the end of a carousel; the images that won't appear until a non-default + tab of some module is clicked? ImageLoader allows you to delay the load of these images until after page load so + that the page is fully functional more quickly. And, by using triggers, you can ensure that the images are loaded + just before the user needs them so that there's no degradation of user experience. +
+ +Approach
++ How can you anticipate when the user will be able to see images? Well, you as a developer know your page, + and you know what actions are available to the user. You can utilize your knowledge to identify user events + that indicate what the user is about to see. +
++ For example, you know that any image lying below the fold won't be visible until the user either scrolls + the page or resizes the browser window. In a tabbed module, you know that the user can't click one of the + tabs until she mouses over that tab. +
++ Consequently, you can use scroll events, mouseover events, or other indicators of user intent to stay one + step ahead of the user and decide when to load images. The ImageLoader Utility lets you do exactly this. +
+ +Triggers
++ Images are grouped together in terms of which user action(s) should trigger their loading. + A trigger is simply any DOM event. Your first step is to create an ImageLoader group object and define its trigger: + +
var myFirstGroup = new Y.ImgLoadGroup({
+ timeLimit: 2
+});
+myFirstGroup.addTrigger('#someDivId', 'mouseover');
+
+
+
+ The timeLimit attribute is a time limit for the group.
+ If the user has not performed the trigger event within the specified time limit, the images are fetched anyway.
+ You can elect to not specify either the time limit or the trigger (indicating the user must perform the trigger event,
+ or there should only be a simple time delay, respectively.)
+
+ You can have as many triggers as you wish for a group.
+ Just add them with the group class's addTrigger method:
+
+
myFirstGroup.addTrigger('#someOtherDivId', 'click');
+
+
++ The trigger conditionals are disjunctive; the first one to fire initiates the image fetching. +
+ +Custom Event Triggers
+
+ You can also specify custom events as triggers. If the event belongs to the Y instance,
+ call addCustomTrigger with the event name:
+
+
myFirstGroup.addCustomTrigger('mycustomevent:imgloadevent');
+
+
+
+ Alternatively, if you have a custom event attached to a local object, you can specify this in the
+ addCustomTrigger call:
+
+
myFirstGroup.addCustomTrigger('mycustomevent:imgloadevent2', myCustomEvent);
+
+
+
+ And this group's images will be fetched upon myCustomEvent.fire('mycustomevent:imgloadevent2');.
+
Adding Images
+Once a group is created, you can add as many images as you'd like to it. There are three types of images:
+-
+
-
+ background image (a
<div>with a background image; URL set instyle.backgroundImage). + Use thebgUrlattribute to register this kind of image. +
+ -
+ source image (an
<img>tag; URL set in aurlattribute). + Use thesrcUrlattribute to register this kind of image. +
+ -
+ png background image (a
<div>with a png background image; for IE6, + sets an alpha filtersrc; for other browsers sets a background image). + Use theisPngandbgUrlattributes to register this kind of image. +
+
+ To add an image to a group, register the DOM ID of the image element and the image URL with the
+ registerImage method:
+
+
myFirstGroup.registerImage({
+ domId: 'idOfDivWaitingForImage',
+ bgUrl: 'http://www.example.com/image/url'
+});
+myFirstGroup.registerImage({
+ domId: 'idOfImgWaitingForImage',
+ srcUrl: 'http://www.example.com/other/image/url'
+});
+myFirstGroup.registerImage({
+ domId: 'idOfDivWaitingForPngImage',
+ bgUrl: 'http://www.example.com/png/image/url',
+ isPng: true
+});
+
+
+
+ This will set the image at http://www.example.com/image/url as the background-image of
+ the <div> with the ID idOfDivWaitingForImage and likewise with the two other image elements.
+
Loading Images Below the Fold
+
+ A group can check its images at the DOM ready state and immediately begin loading those that are above the fold
+ (i.e., inside the current viewport) while delaying the load of those that aren't. Just set a value for
+ the foldDistance property of the group. Images are checked and loaded in a cascading fashion.
+ That is, each image will be loaded only when it comes within foldDistance pixels of the bottom of the viewport.
+ The effect is that images are loaded as needed as the user scrolls down the page. When you set a foldDistance,
+ the group automatically gets window scroll and window resize triggers.
+
var foldGroup = new Y.ImgLoadGroup({
+ foldDistance: 30
+});
+foldGroup.registerImage({
+ domId: 'partwayDownPageImage',
+ bgUrl: 'http://www.example.com/image/url'
+});
+
+
+
+Image Visibility
+
+ You can set your <img> tags to have the CSS property visibility:hidden.
+ This will allow your page to keep its structure until the image is actually loaded. Since these images are probably
+ out of the viewport anyway, this may not make a perceptible difference, but it will help some browsers avoid reflowing
+ the page when deferred images are loaded. To accomplish this using ImageLoader, set the setVisible
+ attribute of the image to true when you register the image; ImageLoader will then set the visibility
+ property to visible when the image is fetched.
+
Using Class Names
+
+ As an alternative to registering each image with a group, you can use CSS class names to group images together.
+ When using this approach, images that are part of the same group should all share a common class name.
+ Each should also have its image set as the element's background image via CSS in the element's style attribute.
+ To prevent the image from loading immediately when the element renders, create a CSS style definition for that
+ class overriding the background image to none. Lastly, set the className attribute of the
+ ImageLoader group.
+
+ The following combination of CSS, HTML, and JavaScript illustrates this approach: +
<div
+ class='yui-imgload-somegroup'
+ style='background-image:url("http://www.example.com/image/url");'>
+</div>
+
+<style>
+ .yui-imgload-somegroup {
+ background:none !important;
+ }
+</style>
+
+<script>
+ someGroup.set('className', 'yui-imgload-somegroup');
+</script>
+
+
+
+
+Important Usage Requirements
+ ++ There are some important things to keep in mind while using the ImageLoader Utility. + Otherwise it may not work the way you expect, or it may have some undesired side effects. +
+ +"src" Attribute of Source Images
+
+ When using ImageLoader with <img> elements (via the srcUrl attribute),
+ leave the src attribute out of the HTML element altogether. Do not set an empty string for
+ the value of src. Some browsers react to this by assuming the empty string means "/", and
+ consequently the browser re-requests the current HTML page and tries to stuff it into the <img> element.
+ This is bad news for performance.
+
+
+ <img id="anImgEl" />
+
+
+ <img id="anImgEl" src="" />
+
Resizing Images
+
+ When resizing <img> elements (via height and width attributes) on the fly,
+ the height and width of the image must be specified in the JavaScript. Do this by setting width/height
+ attributes in the registerImage call. Failure to do this will result in no resizing. Browsers ignore width/height
+ set in the HTML when there is no src attribute. And when the src is finally set, the width/height end
+ up being the image's natural size.
+
+
+ someGroup.registerImage({ domId: "someImgDiv", srcUrl: "http://www.example.com/image/url", width: W, height: H });
+
+
+ someGroup.registerImage({ domId: "someImgDiv", srcUrl: "http://www.example.com/image/url" });
+
