Skip to main content

Need to improve page load performance?
Make the Kessel run in less than 12 parsecs?
This new lightweight method may be the one you're looking for.

So simple, a blathered Ewok could implement.

- (update: )

Using the viewport position to late-load content

Late load images or entire blocks of content dependent upon the page scroll position. The method depicted here is an incredibly lightweight vanilla JavaScript method which even displays content when scripting is unavailable.

A shout-out for Alex Whitlock and Sushma Varadaraj, for helping out with the pre-implementation testing.

Real world implementation now Live on Tesco Summer 2015.

Apologies for the flagrant copyright abuse Mr Lucas Disney lawyer sir, I'm desisting and ceasing as you press send, honest guv.

So how does it work?

Blocks to be late-loaded are encapsulated in <noscript class=idle-load> elements.

Essentially JavaScript replaces each of the tags with a <div class=idle-load-ON> as its parent container, the <div>, approaches the viewport.

Just how simple is this?

Language HTML
<div>
  <noscript class=idle-load>
    <h3>Obi Wan Kenobi</h3>
    <img src="i/obi_wan_kenobi.jpg" alt="">
    <p>A wise and skilled Jedi Master…</p>
  </noscript>
</div>

Add the script.

Language JavaScript
// idleload.2.5.js - 592 bytes gzipped (1.01KB uncompressed)
var idleLoad=function(){function p(a,c){var b,d;c||(c=250);return function(){var f=this,e=+Date.now(),g=arguments;b&&e<b+c?(clearTimeout(d),d=setTimeout(function(){b=e;a.apply(f,g)},c)):(b=e,a.apply(f,g))}}function h(){var a,c;if(b)if(c=b.length)for(;c--;){if(a=b[c].getAttribute("data-"+k)||e,b[c]&&document.documentElement.clientHeight*a>=b[c].parentNode.getBoundingClientRect().top){a=b[c];var h=l,d=document.createElement(m);d.className=a.className.replace(f,f+n);d.innerHTML=a.innerHTML.replace(/&lt;/g,
"<").replace(/&gt;/g,">");a.parentNode.replaceChild(d,a);h&&h(d)}}else window.removeEventListener("scroll",g,!1)}var b,e,k,m,f,n,l,g;return{init:function(a){document.addEventListener&&document.getElementsByClassName&&(f=a.elementClass||"idle-load",b=document.getElementsByClassName(f),n=a.onClass||"-ON",m=a.elementTo||"div",e=(e=0===a.offsetViewportBy?1E-4:a.offsetViewportBy)||1.5,k=a.idleAttribute||"idle",g=p(function(){h()},a.pollDelay),l=a.callbackFunc||!1,window.addEventListener("scroll",g,!1),
h())}}}();

Add configuration options (just before the </body> tag), amend to suit.

Language JavaScript
idleLoad.init({               // All options optional:
  elementClass : 'idle-load', // (default) Class of <noscript> tags to replace.
  onClass : '-ON',            // (default) Added to the class name upon replacement.
  elementTo : 'div',          // (default) Element to replace <noscript>.
  offsetViewportBy : 0.5,     // Viewport: 0 top, 0.5 halfway, 1 bottom, 1.5 (default) half a screen below the viewport.
                              //           May be overridden by a data-idle value on a noscript tag: data-idle='1'.
  idleAttribute : 'idle',     // (default) Data attribute to override offsetViewportBy, uses same values.
  pollDelay : 250,            // (default) How often polling to throttle occurs.
  callbackFunc : function(){} // Call back function on noscript replacement.
});

Done. So simple a blathered Ewok could code right?

The full version is available in the source of the standalone demo.

Scripting - embrace the dark side

It's possible to fire each <noscript> individually by adding a data-idle='1' which acts as an override for the value of offsetViewportBy.
For example the blathered Ewok which should appear below / to the right.

Special FX

Help the aged: IE 6, 7 & 8

Socialise: