This document provides suggestions for optimizing web application and site performance. It discusses minimizing CSS and JavaScript file sizes, simplifying selectors, avoiding expensive operations like DOM lookups and expression evaluation, leveraging browser caching, image optimization techniques like sprites, and reducing blocking of page loads by scripts. The key recommendations are to simplify code, optimize only when needed, and consider maintainability.
5. Session Objective(s):
How to make your site faster today
Principles to remember when building sites
Key Takeaways
Suggestions help in ALL browsers
No magic solutions
Consider maintainability
5
6. “…We are like dwarfs on the shoulders of
giants, so that we can see more than they,
and things at a greater distance, not by
virtue of any sharpness of sight on our part,
or any physical distinction, but because we
are carried high and raised up by their giant
size.quot;
- Bernard of Chartres 1124
6
7. IE8 CPU usage: Top 100 Sites
Layout, Rende
ring, Formattin
16% g, …
JScript & DOM
84%
7
8. IE8 CPU usage: Top AJAX Sites
Layout, Rende
ring, Formattin
g, …
33%
67%
JScript & DOM
8
11. Minimize included styles
Unused styles increase download size
Browser must parse and match all selectors
Failures are expensive!
11
12. Simplify selectors
Complex element selectors are slow
When possible:
Use class- or ID-based selectors
Make element selectors as simple as possible
Use child instead of descendent selectors
Do not mix RTL and LTR styles
Minimizing included styles makes this easier
12
13. Simplify selectors
table tr td ul li {color: green;}
li#pass {color: green;}
ul li {color: purple;}
ul > li {color: purple;}
14. Don't use expressions
Slow – evaluated frequently
Not supported in IE8 Standards Mode!
14
15. Minimize Page Re-layouts
Poor user experience as content moves
Browser performs unnecessary work
15
23. Implicit lookups: Batch changes
function BuildUI2()
{
var elm = document.getElementById('ui');
1 innerHTML
// Generate UI
Reference
var contents = BuildTitle()
+ BuildBody()
+ BuildFooter();
// Replace existing contents with UI
elm.innerHTML = contents;
}
24. Multiple DOM lookups
function CalculateSum()
{
// Retrieve Values
document.body.all
var lSide = document.body.all.lSide.value;
document.body.all
var rSide = document.body.all.rSide.value;
// Generate Result
document.body.all.result.value = lSide
document.body.all
+ rSide;
}
25. Multiple DOM lookups: Cache references
function CalculateSum2()
{
// Cache Element Collection
var elms = document.body.all;
// Retrieve Values
elms
var lSide = elms.lSide.value;
elms
var rSide = elms.rSide.value;
// Generate Result
elms
elms.result.value = lSide + rSide;
}
26. Function lookups
function IterateWorkOverCollection()
{
var length = myCollection.length;
for(var i = 0; i < length; i++)
{
Work
Work(myCollection[i]);
}
}
27. Function lookups: Cache pointers
function IterateWorkOverCollection2()
{
var funcWork = Work;
var funcWork = Work;
var length = myCollection.length;
for(var i = 0; i < length; i++)
{
funcWork
funcWork(myCollection[i]);
}
}
28. Takeaways
Watch for expensive name lookups
Cache repeated lookups to local variables
Optimize only when needed
Consider maintainability
28
31. Parsing JSON
With eval
Requires new script execution context (slow)
Less secure
With custom library
More secure, but even slower
31
32. Parsing JSON: Use the native methods
Built-in JSON methods:
JSON.parse()
JSON.stringify()
toJSON() on prototypes of Date, Number, String,
and Boolean
Native equivalent of the reference parser from
http://wiki.ecmascript.org/doku.php?id=es3.1:json
_support
As safe as http://www.json.org/json_parser.js
but faster
32
42. Minimize DOM interaction
function getElementsByClassName(className, node, tag) {
…
var elements = node.getElementsByTagName(tag);
var elements = node.getElementsByTagName(tag);
var pattern = new RegExp(quot;(^|s)quot; + className +
quot;(s|$)quot;);
elements.length
for(var i = 0, j = 0; i < elements.length; i++) {
elements[i]
if (pattern.test(elements[i].className)) {
classElements[j] = elements[i];
j++;
}
}
return classElements;
}
43. Minimize DOM interaction
function getElementsByClassName(className, node, tag)
{
…
var results = node.getElementsByTagName(tag);
var elements = new Array(results.length);
var elements = new Array(results.length);
while (length--) elements[length] = results[length];
while (length--) elements[length] = results[length];
var pattern = new RegExp(quot;(^|s)quot; + className +
quot;(s|$)quot;);
for(var i = 0, j = 0; i < elements.length i++) {
elements.length;
elements[i]
if (pattern.test(elements[i].className)) {
classElements.push(results[i]); j++;
}
} return classElements;
}
44. Smart use of DOM Methods
Smart use of DOM methods can minimize
overall DOM interaction
nextSibling() better than childNodes[i]
querySelectorAll() better for element groups
44
45. Smart use of DOM methods
function LoopChildren(elm)
{
var nodes = elm.childNodes;
var length = nodes.length;
for(var i = 0; i < length; i++)
{
var node = nodes[i];
nodes[i];
…
}
}
46. Smart use of DOM methods
function LoopChildren2(elm)
{
var node = elm.firstChild;
while(node != null)
{
…
node = node.nextSibling;
}
}
47. Use querySelectorAll for groups
function doValidation2()
{
// Retrieve the required elements by using Selectors
// Selects all form fields with 'required' classes
var reqs = document.querySelectorAll
document.querySelectorAll(quot;.requiredquot;);
// 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 == quot;quot;)
missingRequiredField = true;
}
}
48. Takeaways
Use the native JSON object
Turn large switch statements into lookups
Avoid property access methods
Minimize DOM interaction
Use querySelectorAll for groups
Optimize only when needed
Consider maintainability
49
63. Tools
Fiddler
Inspect network traffic
www.fiddler2.com
neXpert
Fiddler plug-in to aid performance testing
http://www.fiddler2.com/fiddler2/addons/neXper
t.asp
64
64. Takeaways
Reduce the number of requests
Combine external scripts, styles, and images
Use caching
Reduce the size of requests
Use HTTP compression
Use conditional requests
Avoid blocking factors
Put script at end of HTML
65
65. Identify the performance bottleneck
Network / Bandwidth – using Fiddler
JavaScript – using Developer Tools
Aggressive DOM access – using Developer Tools
Reduce, Simplify, Re-factor
Reduce the bytes sent between the client/server
Simplify your code to avoid costly JavaScript and CSS
constructs
Cache DOM properties and function pointers
66