presemtation tier optimizations

21
Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/ Page 1 of 21 Presentation Tier Optimizations: A.k.a. Optimization of Web UI Layer Introduction Performance is the most important attribute for success of any commercial and Enterprise Software. In a client server environment, developers focus a lot on optimizing the Data and Logical Tiers. Optimization of Presentation Tier which is responsible for more than 30 % of performance is usually ignored. The document is developed with the intension to teach the technical staff on Optimizing the Presentation Tier which significantly improves the performance of the Client Server applications. Why is speed important? Google found that the page with 10 results took 0.4 seconds to generate. The page with 30 results took 0.9 seconds. Half a second delay caused a 20% drop in traffic. Half a second delay killed user satisfaction. In A/B tests, Amazon tried delaying the page in increments of 100 milliseconds and found that even very small delays would result in substantial and costly drops in revenue. Reference: http://www.codinghorror.com/blog/2011/06/performance-is-a-feature.html There's plenty of experimental data proving that the slower your Client-Server Application /Website loads and displays, the less people will use it. The converse is also true. That is, if the Client-Server Application/Website is fast, then more people will use it. This follows logically if you think like an information omnivore: the faster you can load the page, the faster you can tell whether that page contains what you want. The user's proximity to your web server has an impact on response times. Where should you start? Any typical Client-Server Application can be divided into 3: 1. Data Tier (also known as Persistence Tier) 2. Application Tier (also known as Processing Tier or Logical Tier) 3. Presentation Tier Data Tier or Persistence Tier is responsible for storing data. It comprises of DMBS, RDBMS, Flat files etc… Application Tier is the tier where the server code like PHP, C# (Asp.NET), Java (JSP) are compiled and executed. It also comprises of the HTTP application server and server processing libraries. Presentation Tier acts as the User Interface. It mainly comprises of HTML, CSS, Client Side Scripts etc… TECHNOLOGY UPDATE

Upload: anup-nair

Post on 26-Jan-2015

113 views

Category:

Technology


2 download

DESCRIPTION

Performance is the most important attribute for success of any commercial and Enterprise Software. In a client server environment, developers focus a lot on optimizing the Data and Logical Tiers. Optimization of Presentation Tier which is responsible for more than 30 % of performance is usually ignored. The document is developed with the intension to teach the technical staff on Optimizing the Presentation Tier which significantly improves the performance of the Client Server applications.

TRANSCRIPT

Page 1: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 1 of 21

Presentation Tier Optimizations: A.k.a. Optimization of Web UI Layer

Introduction Performance is the most important attribute for success of any commercial and Enterprise Software. In a client server environment, developers focus a lot on optimizing the Data and Logical Tiers. Optimization of Presentation Tier which is responsible for more than 30 % of performance is usually ignored. The document is developed with the intension to teach the technical staff on Optimizing the Presentation Tier which significantly improves the performance of the Client Server applications.

Why is speed important? Google found that the page with 10 results took 0.4 seconds to generate. The page with 30 results took 0.9 seconds. Half a second delay caused a 20% drop in traffic. Half a second delay killed user satisfaction. In A/B tests, Amazon tried delaying the page in increments of 100 milliseconds and found that even very small delays would result in substantial and costly drops in revenue. Reference: http://www.codinghorror.com/blog/2011/06/performance-is-a-feature.html

There's plenty of experimental data proving that the slower your Client-Server Application /Website loads and displays, the less people will use it. The converse is also true. That is, if the Client-Server Application/Website is fast, then more people will use it. This follows logically if you think like an information omnivore: the faster you can load the page, the faster you can tell whether that page contains what you want. The user's proximity to your web server has an impact on response times.

Where should you start? Any typical Client-Server Application can be divided into 3:

1. Data Tier (also known as Persistence Tier) 2. Application Tier (also known as Processing Tier or Logical Tier) 3. Presentation Tier

Data Tier or Persistence Tier is responsible for storing data. It comprises of DMBS, RDBMS, Flat files etc… Application Tier is the tier where the server code like PHP, C# (Asp.NET), Java (JSP) are compiled and executed. It also comprises of the HTTP application server and server processing libraries. Presentation Tier acts as the User Interface. It mainly comprises of HTML, CSS, Client Side Scripts etc…

TE

CH

NO

LO

GY

U

PD

AT

E

Page 2: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 2 of 21

Following diagram illustrates the relevance of each Tier.

Organizations primarily focus on optimization of Data Tier and Application Tier

Presentation Tier is usually ignored. Presentation Tier is responsible for more than 30% of Client/Server application performance.

Page 3: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 3 of 21

So the main question is, if the Presentation Tier optimization was so important why is it ignored? Who is to be blamed? Well, in early days, there were no articles on patterns or engineering practices to optimize the Presentation Tier. You still required specialists to

1. Understand the loading pattern of HTTP-Response objects. 2. Optimize the Load pattern of HTTP-Response objects.

Consider the above figure. Whenever user enters a URL, the request is sent from the browser to the server in the form of HTTP request objects. The request is processed by the server and the response is sent back to the client in the form of HTTP response objects. The HTTP response objects include HTML, CSS, Client Side Scripts etc… Most of the response time is spent downloading all the components in the page: Flash, Images, CSS, Client Side scripts, etc... So rather than starting with the difficult task of reengineering your application architecture, it's better to first understand your HTTP content. One of the most important aspects of optimizing the presentation Tier are

1. Reduce HTTP Requests

Reducing the total number of HTTP Requests made to the server by the Clients browser.

2. Reduce HTTP Response

Reduce the total HTTP Response objects sent from server to client.

3. Optimize HTTP Response Objects

Reduce the size of response objects.

Re-Engineer the load pattern for response objects.

Page 4: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 4 of 21

What are primarily considered for optimization?

Total size of data to be loaded on HTTP calls. (Minify Html, CSS and JavaScript to reduce size of response objects)

Time it takes for the browser to read (Parse) the markup language, and client side scripts. (W3C compliant markup is rendered quickly by the Web-Browser.)

Number and size of the multimedia contents like video, photo, and flash.

HTTP server caching of repeated object requests.

Number of Content Delivery Networks (CDN) available from the point of HTTP request.

How do we practically optimize the Presentation Tier? Let’s look at some of the optimization techniques which can be performed on any Client Server application, regardless of its platform (LAMP/JAVA EE/.NET). These include:

1. JavaScript Development Patterns. 2. Load media on Demand. 3. CSS Sprites 4. ETAG HTTP cache 5. CDN – Content Delivery Networks 6. Runtime Compressions 7. W3C compliance

Now let’s look into each in details.

Page 5: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 5 of 21

1. JavaScript Development Patterns JavaScript is used in billions of Web pages to add functionality, validate forms, communicate with the server, and much more. Almost every Client Side Technologies like DOM, AJAX, jQuery, Moo Tools, E4X etc… are one way or the other a derivative of JavaScript. Thus it is very important to follow certain development patters while working with JavaScript. Some of most important JavaScript Development Patterns include:

1. Load JavaScript On-Demand. 2. Compress Your JavaScript (minify files) 3. Place JavaScript at end of Markup.

1. Load JavaScript On-Demand. <script type='text/javascript' src='snip.js'></script>

Vs. If(event ==“true”)

{

var script = document.createElement('script');

script.type = 'text/javascript';

script.src = 'snip.js'; /*Only import the Library on the occurrence of

an event.*/

document.getElementsByTagName('head')[0].appendChild(script);

}

/*import with a random query parameter to avoid caching*/

function $importNoCache(src){

var ms = new Date().getTime().toString();

var seed = "?" + ms;

$import(src + seed);

}

In the above piece of code, the fist line of code imports a JavaScript file “snip.js” into an HTML document. Now the next 7 lines of code which follow the first line, also imports the “snip.js” into an HTML document, but there is a difference. In the second version, we can apply a condition/event and only when the condition/event is true, is when we actually import the JavaScript file. This is useful pattern as we delay the load of heavy JavaScript libraries until they are actually needed. Note: The remaining line of code towards the end is optional. They are useful when you want to avoid the caching of the JavaScript files while making request. This is accomplished by adding seed variable while making the request. In the above sample, time acts as the seed variable.

Page 6: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 6 of 21

2. Minify JavaScript Run JSLint (online or downloadable version) to analyze your code and make sure it is well-formatted. 1. Use Rhino to compress your JavaScript. 2. Rhino will remove spaces, comments and shorten variable names where appropriate.

Using Rhino, we should pack the original JavaScript and deploy the packed version to my website. -------------------------------------------------------------------------------------------------------------------- Before Minifying: function todaydate()

{

/*Variable declaration*/

var today_date= new Date();

var myyear=today_date.getYear();

var mymonth=today_date.getMonth()+1 /*No semicolon, but will work */

var mytoday=today_date.getDate();

/*Action*/

document.write(myyear+"/"+mymonth+"/"+mytoday)

} -------------------------------------------------------------------------------------------------------------------- After Minifying: function todaydate(){var today_date= new Date(); var

myyear=today_date.getYear();var mymonth =today_date.getMonth()+1; var

mytoday=today_date.getDate();document.write(myyear+"/"+mymonth+"/"+myto

day)}

------------------------------------------------------------------------------------------------ ----------------- If you compare the before Minifying and after Minifying, you will realize that that all the white space is removed, the comments are deleted and the code is well formatted. The minified JavaScript code will be smaller is size. Developers should also remember the naming convention. Standard Naming Convention is adding “.min” in file name. Usually a prefix just before the extension. Sample: When you try to download the latest version of jQuery library, it always provides you with 2 options. One is the Source version and other is the Minified version.

jquery-1.x.x.js (Source version or Developer version) jquery-1.x.x.min.js (Minified version or Deployment Version) Reason is that, the source version is the one that is understood by the developer as it contains comments and is properly spaced and formatted. The Minified version is intended for consumption/deployment purposes only.

Page 7: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 7 of 21

3. Place your JavaScript at the end of your HTML.

Notice how Google analytics and other statistics tracking software want its code to be placed right before the closing </body> tag. This allows the majority of page content (like images, tables, text) to be loaded and rendered first by the Parser. The user sees content loading, so the page looks responsive. At this point, the heavy JavaScript can begin loading near the end. This is also useful for SEO (Search Engine Optimization) as Google/MSN/Yahoo AI crawling Bots also prefer this pattern. Search Engine Crawlers usually only index Markup. They do not index Client Side Scripts. Hence they prefer this pattern. Sample

<html><head></head><body>

<!--Some Body Code-->

<button type="button" onclick="displayDate()">Display

Date</button>

<!--Some Body Code-->

<script type="text/javascript">

function displayDate()

{document.getElementById("demo").innerHTML=Date();}

</script>

<script src="myjs.js"></script>

</body></html>

In the above code the inline JavaScript and the external JavaScript import code are placed just before the end of the body tag.

Page 8: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 8 of 21

2. Load Media On-Demand Yahoo.com loads images when they are in browsers viewable zone.

jQuery-Images-OnDemand is a very useful jQuery Library which allows you to achieve the same. It loads images only when they are brought in the viewable zone of the browser. URL to download this library: http://code.google.com/p/jquery-images-ondemand/

All that is needed is to append an additional CSS Class ”img-ondemand" to the “img” object as

follows:

<img class="class1 img-ondemand" longdesc="my_pic.jpg" src=

pix.gif" />

This is a very simple script to load images On-Demand. Using this you avoid to load all page images and get a faster web page. Note on HTML5: With HTML5, Multimedia objects can also be extracted using jQuery or DOM, as they can be specified by Tags instead of embedding using an OBJECT Tag. This will be very useful as it will allow us to delay the load of video and audio much similar to images.

Page 9: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 9 of 21

3. CSS Sprites CSS sprites are a way to reduce the number of HTTP requests made for image resources referenced by your site. Images are combined into one larger image at defined X and Y coordinates. Having assigned this generated image to relevant page elements the background-position CSS property can then be used to shift the visible area to the required component image. Consider the following image: Before Sprite

CSS Code: /* Five different images.*/ #item1 a:hover{background: url('img_1.gif')}

#item2 a:hover{background: url('img_2.gif')}

#item3 a:hover{background: url('img_3.gif')}

#item4 a:hover{background: url('img_4.gif')}

#item5 a:hover{background: url('img_5.gif')}

HTML/XHTML Code: <div id="item1"></div> <!—This will show the first image-->

<div id="item2"></div> <!—This will show the second image-->

<div id="item3"></div> <!—This will show the third image-->

<div id="item4"></div> <!—This will show the fourth image-->

<div id="item5"></div> <!—This will show the fifth image--> In the above, depending on the number of images the number is HTTP requests increases. Using CSS Sprite, we can reduce the number of HTTP request.

Page 10: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 10 of 21

Consider the following sample which makes use of CSS Sprite to load images. After Sprite

CSS Code: /* One image. Parts of the image are referenced. */ #item1 a:hover{background: url('merged_image.gif') 0 -45px;}

#item2 a:hover{background: url('merged_image.gif') -46px -45px;}

#item3 a:hover{background: url('merged_image.gif') -92px -45px;}

#item4 a:hover{background: url('merged_image.gif') -137px -45px;}

#item5 a:hover{background: url('merged_image.gif') -183px -45px;}

HTML/XHTML Code: <div id="item1"> </div> <!—This will show the first image-->

<div id="item2"> </div> <!—This will show the second image-->

<div id="item3"> </div> <!—This will show the third image-->

<div id="item4"> </div> <!—This will show the fourth image-->

<div id="item5"> </div> <!—This will show the fifth image-->

You combine an unlimited number of images into one and then only display parts of that image using CSS. The origin of the term "sprites" comes from old school computer graphics and the video game industry. The idea was that the computer could fetch a graphic into memory, and then only display parts of that image at a time, which was faster than having to continually fetch new images. The sprite was the big combined graphic. CSS Sprites is pretty much the exact same theory: get the image once, shift it around and only display parts of it, saves the overhead of having to fetch multiple images.

Page 11: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 11 of 21

CSS Sprites – Image Merge Pattern

Page 12: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 12 of 21

4. HTTP Cache The following illustrates the normal time based Caching.

Comparing versions with the modification time generally works, but could lead to problems. What if the server’s clock was originally wrong and then got fixed? What if daylight savings time comes early and the server isn’t updated? The caches could be inaccurate. ETags to the rescue. Caching – ETag (Entity tags) An ETag is a unique identifier given to every file. It’s like a hash or fingerprint: every file gets a unique fingerprint, and if you change the file (even by one byte), the fingerprint changes as well. Instead of sending back the modification time, the server can send back the ETag (fingerprint): ETag: ead145f File Contents (could be an image, HTML, CSS, Javascript...) The ETag can be any string which uniquely identifies the file. The next time the browser needs logo.png, it can have a conversation like this:

Page 13: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 13 of 21

5. CDN A content delivery network or content distribution network (CDN) is a system of computers containing copies of data, placed at various points in a network so as to maximize bandwidth for access to the data from clients throughout the network.

A client accesses a copy of the data near to the client, as opposed to all clients accessing the same central server, so as to avoid bottlenecks near that server. Content types include web objects, downloadable objects (media files, software, and documents), applications, real time media streams, and other components of internet delivery (DNS, routes, and database queries). An important point to note here is that they are not Replicated Servers. Notable Commercial CDN providers include

Akamai Technologies

Amazon CloudFront

AT&T

Bitgravity

CDNetworks

Chinacache

Cotendo

EdgeCast Networks

Highwinds Network Group

Internap

Level 3 Communications

Limelight Networks

Microsoft Windows Azure CDN

Mirror Image Internet

NetDNA

Page 14: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 14 of 21

6. Runtime – Compressions HTTP compression, otherwise known as content encoding, is a publicly defined way to compress textual content transferred from web servers to browsers. HTTP compression uses public domain compression algorithms, like gzip and compress, to compress XHTML, JavaScript, CSS, and other text files at the server. This standards-based method of delivering compressed content is built into HTTP 1.1, and most modern browsers that support HTTP 1.1 support ZLIB inflation of deflated documents. In other words, they can decompress compressed files automatically, which saves time and bandwidth. The following diagram illustrates HTTP compression.

This is an obvious and effective optimization which is applied at both Application Tier and Presentation Tier.

Configuring HTTP Compression in IIS 7: http://technet.microsoft.com/en-us/library/cc771003%28WS.10%29.aspx Note: It is not enabled by default. Configuring HTTP GZIP Compression in APACHE http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/ Note: Need to install GZIP modules and configure with Apache.

Page 15: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 15 of 21

7. Valid W3C compliant pages http://validator.w3.org/ W3C Compliance helps insure that your website is accessible from a number of devices; from different browsers to the growing number of surfers using PDA's and cellular phones. So the question is how it is relevant to performance. The reason is that W3C compliant documents can be quickly read and rendered by the browser, without it getting confused. This helps in avoiding a delay in rendering and as we stated in the beginning, every millisecond counts. Now let’s look at the sample below: <html><head></head><body>

<!--Some Body Code-->

<button type="button" onclick="displayDate()">Display Date</button>

<!--Some Body Code-->

<script type="text/javascript">

function displayDate()

{document.getElementById("demo").innerHTML=Date();}

</script>

<script src="myjs.js"><!--Forgot to close </script> tag….Not a W3C compliant

document-->

</body><!--Ensure Page W3C compliance to avoid delay in rendering by web-

browser-->

</html>

In the above code the developer forgot to close the </script> tag. This makes the document non W3C compliant. However the page would still be rendered properly in most of the modern browsers. Though the page is rendered, it takes time for the browser to render the page. Developers should remember that more W3C compliant the page, faster the page rending speed.

Page 16: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 16 of 21

How do we test HTTP Response of our application? There are two types of test which you can perform on your application.

1. Online Test - WebPageTest.ORG from AOL. 2. Offline Testing - YSlow plug-in for Firebug in Firefox

1. Online Testing WebPagetest.ORG is an AOL sponsored website which provides testing the performance of web pages from multiple locations/configurations and consuming the results in a friendly web interface. URL is http://www.webpagetest.org When you enter the URL the following Screen appears:

Here you enter the URL which you want to test and press “Start Test”. The site performs testing and provides the following 2 types of information:

1. Optimization Checklist. 2. Waterfall Load Pattern.

Now let’s look at both in details.

Page 17: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 17 of 21

1. Optimization Checklist As the name points out, it provides a list of things which needs to be optimized by the developer.

The Checklist includes

1. First Byte Time Applicable Objects: Time to First Byte for the page (back-end processing + redirects) What is checked: The target time is the time needed for the DNS, socket and SSL negotiations + 100ms. A single letter grade will be deducted for every 100ms beyond the target.

2. Keep-Alive

Applicable Objects: All objects that are from a domain that serves more than one object for the page (i.e. if only a single object is served from a given domain it will not be checked) What is checked: The response header contains a "keep-alive" directive or the same socket was used for more than one object from the given host.

3. GZIP Text

Page 18: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 18 of 21

Applicable Objects: All objects with a mime type of "text/*" or "*javascript*" What is checked: Transfer-encoding is checked to see if it is gzip. If it is not then the file is compressed and the percentage of compression is the result (so a page that can save 30% of the size of its text by compressing would yield a 70% test result)

4. Compress Images

Applicable Objects: Any object with a mime type of "image/*" What is checked: GIF - All pass

PNG - Must be 8 bit or lower (no 24-bit PNGs will pass) JPEG - Within 10% of a photoshop quality 50 will pass, up to 50% larger will warn and anything larger than that will fail.

The overall score is the percentage of image bytes that can be saved by re-compressing the images.

5. Cache Static

Applicable Objects: Any non-html object with a mime type of "text/*", "*javascript*" or "image/*" that does not explicitly have an Expires header of 0 or -1, a cache-control header of "private", "no-store" or "no-cache" or a pragma header of "no-cache" What is checked: An "Expires" header is present (and is not 0 or -1) or a "cache-control: max-age" directive is present and set for an hour or greater. If the expiration is set for less than 30 days you will get a warning (only applies to max-age currently).

6. Combine CSS/JS

Applicable Objects: All css and javascript objects What is checked: If multiple files of the same type are served then each additional css file beyond 1 will subtract 5 percent and each Javascript file beyond the first wil subtract 10 percent

7. Use A CDN

Applicable Objects: All static non-html content (css, js and images) What is checked: Checked to see if it is hosted on a known CDN (CNAME mapped to a known CDN network). The known CDN's are Akamai, Amazon CloudFront, Coral Cache, Edgecast, Google, Highwinds, Internap, Limelight, Mirror Image, Panther and Yahoo

8. Minify JS

Applicable Objects: All html, javascript and json responses What is checked: Javascript will be run through jsmin. If the original content was gzip encoded, the minified version will also be gzipped for comparison. If > 5KB or 10% is saved then it will fail. If > 1KB is saved, it will warn, otherwise it will pass.

9. Cookies Applicable Objects: All requests What is checked: Any request for a static object that sends up a cookie will fail. All other requests that send up cookies will warn.

Page 19: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 19 of 21

2. Waterfall Load Pattern Calculating the load and load pattern is probably the trickiest issue in conducting website performance tests. WebPageTest.org provides HTTP Response Object Load Pattern. It also provides information on the time at which the HTTP response objects were loaded. The following screen displays how the data is displayed.

Page 20: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 20 of 21

2. Offline testing If your site is not hosted and your want to test your application during the development process, then you can make use of YSlow. YSlow is a plug-in for Firebug in Firefox, from Yahoo Developer Network. YSlow analyzes web pages and suggests ways to improve their performance based on a set of rules for high performance web pages. Features:

Grades web page based on one of three predefined rule set or a user-defined rule set;

It offers suggestions for improving the page's performance;

Summarizes the page's components;

Displays statistics about the page;

Provides tools for performance analysis, including Smush.it and JSLint. URL to download YSlow: http://developer.yahoo.com/yslow/

YSlow plug-in for Firebug in Firefox

Page 21: Presemtation Tier Optimizations

Anup Hariharan Nair April 16, 2011 http://www.HiFiCoding.com/

Page 21 of 21

References / Sources for further Reading Yahoo Client-Server Developer Reference :

http://developer.yahoo.com/performance/rules.html

Google Client/Server Developer reference: http://code.google.com/speed/page-speed/docs/rules_intro.html

W3C standards compliant Web sites http://www.w3.org/QA/2002/07/WebAgency-Requirements

http://technet.microsoft.com/en-us/library/cc771003%28WS.10%29.aspx

http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/

http://code.google.com/p/jquery-images-ondemand/

http://www.codinghorror.com/blog/2011/06/performance-is-a-feature.html

http://www.webpagetest.org