Make your page lighter – defer images to load

June 21st, 2009   Filed Under Javascript, Tips & Tricks, comparisons, jQuery, optimization, snippet, utilities  

As web professionals we are generally concerned with the page load time, especially when we have a lot of images loading from third party servers which adds up to the page performance.
Portal developers are mostly worried and concerned with this problem.

I and my friend Shon Thomas have tried putting some thoughts and developed a jQuery plugin which will solve this problem.
The technique used here goes as follows:
We do not assign the “src” value to the images we want to load dynamically. Instead assign that URI in a different validator-friendly attribute. For example, you can use “class” or “longdesc”.
Upon scrolling the page, the plug-in detects the images in the viewport area of the browser window and swaps longdesc(or class) with src.

In both the attributes(class and longdesc) I don’t see any problem and they can be used as per your convenience and belief.There could be some argument regarding usage of both of these attributes; But as far as I think I have my reasonable words for both.
1) class: 99% of the time you don’t assign a class name to any image, instead you control them with their parent elements. Even then, if you are so specific, use longdesc.
2) longdesc: longdesc is a very rarely used attribute. I don’t often see people using this attribute on the content images. Even then, if you are specific then either use class attribute or don’t use this functionality for that particular image(as simple as that).

The image html that your server spits should be somewhat like this:

    <img src="http://o.aolcdn.com/shopping.aol.com/img/notavailable.gif" longdesc="http://ai.pricegrabber.com/pi/7/19/48/71948063_160.jpg" alt="Dansko Reese Dress Pumps - Calfskin Leather - For Women" title="Dansko Reese Dress Pumps - Calfskin Leather - For Women"/>

Source Code: The source code below is the plug-in which can go in your jquery plugin file(s) or can get included as a standalone include.

/**
 * jQuery plugin: Lazy Image Loader
 * version: 3.0
 * Author: Vivek Pohre,Shon Thomas
 * Website: (http://www.vivekpohre.com)
 * Example: call lzload() at or after document ready
 */

function lzload(){
    var w=window,adv=30,vph,tmpLD,nowView,collImg,imgTop,scrTop,ci;
    function getVPH(){
	    //DETERMINE WINDOW VIEWPORT HEIGHT ALWAYS TO AVOID RESIZING BROWSER ERROR
	    if(typeof (vph = w.innerHeight?w.innerHeight:$(w).innerHeight()) != "Number")
	        vph = document.documentElement.clientHeight;
    };

    //SAVE THE Y AXIS IN TOP ATTRIB
    getVPH();//GET THE VIEWPORT HEIGHT
    imgTop = 0;//INIT IMGTOP TO ZERO--TEMP VAR
    collImg = $("#content img").filter(':[longdesc]');//COLLECT ALL IMAGES HAVING longdesc ATTR
    collImg.each(function(){
    	imgTop = $(this).offset().top;
    	$(this).attr("top",imgTop);
    });
    $(w).bind("scroll",function(){loadImgs()}).bind("resize",function(){getVPH();loadImgs()});//ATTACH SCROLL & RESIZE EVENT TO WINDOW
    $.loadImgs = loadImgs = function(imgSet){//MAKE loadImgs FUNCTION PUBLIC
    	ci=(imgSet)?imgSet.show():collImg;//DECIDE COLLECTION FROM PASSED OR ALL DOM IMAGES
        scrTop = $(w).scrollTop();
        //DETERMINE THE Y-AXIS IN THE VIEWABLE AREA
        nowView = (scrTop+vph+adv);
        ci.filter(':[longdesc]').filter(':visible').each(function(i){
            if($(this).attr("top")<nowView){
            tmpLD = $(this).attr("longdesc");
            if(typeof tmpLD!='undefined')
               $(this).attr("src",tmpLD)[0].removeAttribute("longdesc",0);
            }
        });
        ci=collImg;
    };
    loadImgs();
    $("#content img").error(function(){
		$(this).attr("src","http://o.aolcdn.com/shopping.aol.com/img/notavailable.gif");
	});
}

www.in.com

August 21st, 2008   Filed Under Good to know, comparisons  

A very desi mash-up has taken place and somehow I have become unaddicted from my gmail. Its not that I am boasting for http://www.in.com

Let us see the features there. You get all of the following in one site:

  1. Read Current Affairs, Entertainment, Sports, Science & Tech,Business
  2. Listen to online music(most of your desi stuff… regional too :) )
  3. Watch videos mashed up from different sources(kinda great)
  4. Play games .. (this is exiting)
  5. Find flights, hotels, matrimonial etc
  6. And last but not least an email system with kinda better interface than gmail (I liked the inline forwarding, deleting and junking your emails)

The email system I liked the most in my one day of use. Its great looking and great using stuff. Plus it gives an identity to all indians to use a in.com as their email id. Thats coool.

Listen to music online while you hang around with your emails. I have literally put a forwarding rule in my gmail to read all the emails on in.com

What is missed here is a embedded chat and a social networking like orkut. But I believe that the makers of in.com should be working on the same to give a in-country competition to Google!!

Voice based search in Hyderabad

April 25th, 2008   Filed Under Good to know, Technology, comparisons, gyan  

Google has launched yet another great utility; The phone based search in Hyderabad for local searches about movies, restaurants and other petty/large businesses.

This is the way it works: You call 180041999999 and ask about a Chinese restaurant and then ask google to forward your call to that restaurant to book a table for you.

But this service is not very much different from justdial service already there in all the major cities of India.

Substitute for the for loop

March 26th, 2008   Filed Under Good to know, Javascript, comparisons, gyan  

Today I came to know a new trick of looping collections. Generally we do a for loop and have i or any other variable as the counter. An alternative to this could be something like this:

var ar = [0,1,2,3,4]; //array
while(ar.length != 0)
{
  document.write(ar[0]);
  ar.shift();
}			//displays 01234

If you have a set of nested for loops which in turn calls other functions which has some loop, and if the counter variable name is same then some browsers forget the scope and reinitializes the variable or shows up the latest  value that was set by the latest loop before it lands back to the host loop.

This while construct can save you some lines as well as risk of i(can i call it i-risk? like i-pod???)

Isn’t it Good to know !!

Internet Explorer 8 Beta - Download

March 7th, 2008   Filed Under browser, comparisons, debuggers  

Download Windows Internet Explorer 8 Beta for Windows XP

http://www.microsoft.com/downloads/thankyou.aspx?familyId=1a2e3ddd-b38b-439d-bba7-f179a5d3ecaf&displayLang=en

Microsoft has released its Beta version of highly disgussed(disgusting discussions) IE 8. You can download it from the following link. By default you will be prompted to download Silverlight. You can download it if you wish to.

However, this version of browser will not be installed on checked(debug) version of Windows Vista, Windows Vista SP1, or Windows Server 2008.

IE 8 Installer Screenshot

What does it copy? Copies so many things from Firefox and its plugins.
Restore Session: Just as FF plugin, it restores the previous session of opened tabs if because of some exception your browser closed unexpectedly.
IEr Bug: Just removed the F from the Firebug and has given almost the same functionalities as Firebug plugin for Firefox. Just removed the “flexibility” and ease Firebug provides you. But appreciate the copy, as it will reduce a lot of unwanted efforts for the UI developers.
Compatibility Modes: While debugging, you can change the browser version compatibility to test if it works with IE5, IE7 and IE8… oops missed IE6.. maybe in the final release they will add IE6.
No live CSS edit: As you get a live css edit in Firefox, here you cannot do that. You need to go to each and every element on the HTML tab and turn on or off the applied styles. No way to add new CSS Text.
Inspect: Here it is “Select element by click”, but does pretty much the same thing. Good CTRL + C. But oops… while inspecting in FF on an element the click event is not registered for the element, but it is transferred to Inspector. IE8 … I think thats a bug probably!!
Activities: A good add-on feature that enables your users to find for contextual services like map, restaurants etc etc in place. This is an extendible tool for the users. You can even copy text to you blogs or web pages. Microsoft appreciates copying?? Thats just a prank… but its cool thing to have.
WebSlices: WebSlices is a new feature for websites to connect to their users by subscribing to content directly within a webpage. WebSlices behave just like feeds where clients can subscribe to get updates and notify the user of changes
CSS 2.1: Hmm sounds good
Data URI Support: Now you can embed your images as you can do it in Firefox: <img alt=”Image fed from data url” src=”data:image/png;base64,iVBORw0KGgoAAA…” />. Good to have for the bloggers who don’t want to have images repository anywhere.
Versioning and Cross-document Interaction: This is just what I wished. I told that to Sudipto. Internet Explorer 8 introduces the IE8 standards mode by default—this lets Web designers use the latest rendering features available in Internet Explorer 8. In addition to layout changes, IE8 standards mode will also affect the behavior of scripted APIs (DOM).
To opt-out of IE8 standards mode, the META tag may be used to obtain IE7 compatibility mode:
<meta http-equiv="X-UA-Compatible" content="IE=7">
Whooooo Hoooooo
But we need compatibility with IE6 and Quirks too.

Now the copies from FF3:
AJAX Navigation: Enables users to navigate back and forth without leaving the AJAX application and could be used navigating a page without performing a traditional full navigation. This allows websites to trigger an update to browser components like the address bar by setting the window.location.hash value, firing an event to alert components in the page and even creating an entry in the travel log.

DOM Storage: Concept pretty much around classic asp session variables, but will not be available in previous versions or other browser vendors. This is a simple-to-use method for storing and retrieving strings of key/value pair data. Data can be stored per tab instance for a session or persisted to the local machine. This allows pages to cache text on the machine which reduces the effect of network latencies by providing faster access to pre-cached data. Several innovative uses are possible. For example, use this in combination with the new network connectivity event to allow a page to cache data if it detects that the computer is offline.

Connectivity events allow websites to check when the user is connected to the network and receive notification of connectivity changes. FF you inspire.

Six connections per host instead of two for broadband scenarios and a scriptable property allow for more improved performance by allowing parallelization of downloads in Internet Explorer 8. In addition, this increases functionality by ensuring a request is not blocked to a host if two connections already exist. Websites can optimize their downloads based on a scriptable property.

XMLHTTPRequest Enhancements include a timeout property that can be set to cancel the request if necessary, allowing developers to manage the request better.

Cross domain requests(XDR): A new jargon, but also a feature to communicate across domains. Firefox 3 has also done the same. I am not sure about the code we need to write to allow this feature. But suspect to be different from Firefox … so again and if… else perhaps.

Selectors API: This is the most wanted feature. Copied from jQuery. This enables you to select your web page elements like CSS. For Example:

For selecting some required fields in your form you write something like this:

function doValidation(){ // Retrieve all the required elements by ID
var name = document.getElementById('fld_name');
var empnum = document.getElementById('fld_emp');
var ssn = document.getElementById('fld_ssn');
var ccnum = document.getElementById('fld_ccNum');
var bribe = document.getElementById('fld_cost');
// Set the flag to false by default
var missingRequiredField = false;
// Validate each of the elements
if (name.childNodes[1].value == "") missingRequiredField = true;
if (empnum.childNodes[1].value == "") missingRequiredField = true;
if (ssn.childNodes[1].value == "") missingRequiredField = true;
if (ccnum.childNodes[1].value == "") missingRequiredField = true;
if (bribe.childNodes[1].value == "") missingRequiredField = true;

But now with Selector API you do this:

function doValidation () {
// Retrieve the required elements by using Selectors
// Selects all the form fields with 'required' classes
var reqs = document.querySelectorAll(".required");
// Set the flag to false by default
var missingRequiredField = false;
// Validate that the form data is not empty
for (var i = 0; i < reqs.length; i++)
{
if (reqs[i].value == "") missingRequiredField = true;
}

Coool No?
Whatever it copies doesn’t actually matter too much because, its all the need of the time. And after all its a race. To compete one need to imitate all that is needed.