don't make me wait! or building high-performance web applications
TRANSCRIPT
“Don’t make me wait”
or
Building High-Performance
Web Apps
Stoyan Stefanov, Yahoo! Brownbag at eBay August 11, 2009
About me • Yahoo! Search • Yahoo! Exceptional Performance • YSlow 2.0 architect • http://smush.it • Books, articles • http://phpied.com
Importance of performance
• Is it dev? QA? Afterthought? • Developers love it • But is it good for business?
Importance of performance
• Self-regulating system • Slow down = lose users • We all hate slow pages
Importance of performance
1sec = -2.8% revenue
Importance of performance
Gets worse with time
After-effect
Importance of performance
• Yahoo!: 400 ms slower = 5-9% drop in full-page traffic
Importance of performance
Slower pages get less traffic
Importance of performance
From 4-6 seconds to 1.5 seconds
“The premature optimization…
• … is the root of all evil” Knuth • “Make it right before you make it fast” Crockford
Measure, measure, measure
• measure • profile • monitor
On trade-offs
“…everything has its drawbacks, as the man said when his mother-in-law died, and they came upon him for the funeral expenses”
Jerome K. Jerome Three man in a boat
request HTML sent
onload page settles
conception birth graduation marriage? R.I.P.
User perceived “onload” happens somewhere here
request
The Life of Page 2.0
The waterfall
The Waterfall
1. Less stuff 2. Smaller stuff 3. Out of the way 4. Start early
The Waterfall
1. Less stuff 2. Smaller stuff 3. Out of the way 4. Start early
Less HTTP requests
• Combine components
Less HTTP requests
• Before:
<script src="jquery.js"></script> <script src="jquery.twitter.js"></script> <script src="jquery.cookie.js"></script> <script src="myapp.js"></script>
Less HTTP requests
• After:
<script
src="all.js" type="text/javascript">
</script>
Less HTTP requests
• Saved 3 HTTP requests
Less HTTP requests
• repeat for CSS:
<link
href="all.css" rel="stylesheet" type="text/css”
/>
Less HTTP requests
• CSS sprites for background images
background‐position: ‐22px ‐0px; width: 12px; height: 10px;
Less HTTP requests
CSS sprites • Before: 15 requests, 6.8 K • After: 1 request, 1.4 K
Less HTTP requests
• CSS sprites – a pain, but there are tools
http://csssprites.com http://spritegen.website‐performance.org/
Less HTTP requests
• Inline images with data: scheme
Less HTTP requests
• data: URI scheme
$ php ‐r "echo base64_encode(file_get_contents('my.png'));” iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC
Less HTTP requests
• data: URI scheme
background‐image: url("data:image/png;base64,iVBORw0KG...");
Less HTTP requests
• data: URI scheme
<img src="data:image/png;base64,iVBOR..." />
Less HTTP requests
• data: URI scheme • works in IE!...
Less HTTP requests
• data: URI scheme • works in IE8!
Less HTTP requests
• data: URI scheme • MHTML for IE < 8
http://www.phpied.com/mhtml-when-you-need-data-uris-in-ie7-and-under/ http://www.hedgerwow.com/360/dhtml/base64-image/demo.php
Less HTTP requests - drawback
• atomic components • invalidated by small changes
• need to schedule changes
Less stuff? Cache
• Cache is less universal than we think • You can help
http://yuiblog.com/blog/2007/01/04/performance-research-part-2/
“never expire” policy
• Static components with far-future Expires header • JS, CSS, img
ExpiresActive On ExpiresByType image/png "access plus 10 years"
Inline vs. external
• a.k.a. less http vs. more cache • how about both?
Inline vs. external
• First visit:
1. Inline 2. Lazy-load the external file 3. Write a cookie
Inline vs. external
• Later visits:
1. Read cookie 2. Refer to the external file
Less stuff – duh!
• No 404s • No duplicates • No near-duplicates
Duplicates
• 2903384828078080_1.jpg • 2204648665418080_1.jpg • 3801476378448080_1.jpg • 3801476377438080_1.jpg
Near duplicates
• 30x30 vs. 49x49
• Rounded corners, shadows
The Waterfall
1. Less stuff ✔ 2. Smaller stuff 3. Out of the way 4. Start early
The Waterfall
1. Less stuff 2. Smaller stuff 3. Out of the way 4. Start early
Gzip
Gzip
• What to gzip?
HTML, XHTML, XML, W00TChaMaCallitML, CSS, JS, JSON, HTC,
plain text… all but binary
• (btw, check those older SWFs too)
Gzip
• How to gzip?
AddOutputFilterByType DEFLATE text/html text/… Header append Vary Accept‐Encoding
http://www.sitepoint.com/article/web‐site‐optimization‐steps
Minify
• Before /** * The dom module provides helper methods for * manipulating Dom elements. * @module dom * */
(function() { var Y = YAHOO.util, // internal shorthand getStyle, // for load time browser branching setStyle, // ditto propertyCache = {}, // for faster hyphen converts reClassNameCache = {}, // cache regexes for className document = window.document; // cache for faster lookups
YAHOO.env._id_counter = YAHOO.env._id_counter || 0;
Minify
• After (function(){var B=YAHOO.util,K,I,J={},F={},M=window.document;YAHOO.env._id_counter=YAHOO.env._id_counter||0;
Minify
• YUI Compressor • Minifies JS and CSS • Tolerates * and _ hacks • More than minification
Minify
• Minify inline code too
Gzip or minification?
• 62,885 bytes - original jQuery (back in Aug 2007)
• 31,822 - minified with the YUI Compressor • 19,758 - original gzipped
• 10,818 - minified and gzipped
http://www.julienlecomte.net/blog/2007/08/13/
FTW
Minify
• minify HTML? • dangerous • write minified HTML
echo '<div class="my">', '<p>', $db‐>get('name'), '</p>', '<div>';
Minify
• Strip quotes? No closing tags? • Some sites do
<body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="...." topmargin=3 marginheight=3><textarea id=csi style=display:none>
Minify
• Relative URLs
Relative URLs on my blog
>>> document.links.length 204 >>> … loop … indexOf(‘http://www.phpied.com’) 130 >>> ‘http://www.phpied.com’.length 21 >>> 21*130/1024 2.666015625
Relative URLs on my blog
• Compare: • 2.66K - absolute links • 1.4K - sprite of 15 elements
Images
• http://smush.it
Images
1. No GIFs, PNG8 2. Crush PNGs 3. run JPEGs through jpegtran 4. Gifsicle for animations
http://yuiblog.com/blog/2008/11/14/imageopt-3/
Loss- less
Images – progressive JPEG
• for images ~10K+
Images
• eBay homepage could save 20% image sizes
• Search –> 10%+ • Item -> 30% (50K+)
Images – duh!
1. Don’t scale in HTML 2. Generated images should
be crushed PNGs too
Images
• It’s only human to forget • All you need is a process so
you don’t have to remember
204
• The world’s smallest component? • 204 No Content
<?php header("HTTP/1.0 204 No Content"); // .... do your job, e.g. logging ?>
http://www.phpied.com/204-no-content/
The Waterfall
1. Less stuff ✔ 2. Smaller stuff ✔ 3. Out of the way 4. Start early
The Waterfall
1. Less stuff 2. Smaller stuff 3. Out of the way 4. Start early
Free-falling waterfalls
• Less DNS lookups – fetch components from not more than 2-4 domains
• Less redirects • Blocking JavaScript/CSS
Not free-falling
JavaScript rocks!
• But also blocks
html
js
png
png
Non-blocking JavaScript
• Include via DOM
var js = document.createElement('script'); js.src = 'myscript.js'; var h = document.getElementsByTagName('head')[0]; h.appendChild(js);
html
js
png
png
Non-blocking JavaScript
• And what about my inline scripts?
• Setup a collection (registry) of inline scripts
Step 1
• Inline in the <head>:
var myapp = { stuff: [], };
Step 2
• Add to the registry
Instead of: <script>alert('boo!');</script> Do: <script> myapp.stuff.push(function(){
alert('boo!'); }); </script>
Step 3
• Execute all
var l = myapp.stuff.length; for(var i = 0, i < l; i++) { myapp.stuff[i](); }
Blocking CSS?
But they do block: • In FF2 • When followed by
an inline script
The Waterfall
1. Less stuff ✔ 2. Smaller stuff ✔ 3. Out of the way ✔ 4. Start early
The Waterfall
1. Less stuff 2. Smaller stuff 3. Out of the way 4. Start early
Cookies
• less cookies
• no cookies
• www vs. non-www
3000 bytes of cookies cost 78ms
flush() early
html
png
js
css
html
png
js
css
✔
flush() <html> <head> <script src="my.js"
type="text/javascript"></script> <link href="my.css"
type="text/css" rel="stylesheet" /> </head> <?php flush() ?> <body> ....
Chunked encoding
HTTP/1.1 200 OK Content‐Type: text/plain Transfer‐Encoding: chunked
25 This is the data in the first chunk
1C and this is the second one
0
Chunked encoding
• Progressive rendering
- Semantic app chunks
vs.
- Server-level chunks
Progressive rendering Chunk #1
Chunk #2
Chunk #3
Progressive rendering
• Server-level flush:
bing.com – every 1 or 2K
google (ungzip) – every 4K
Progressive + source order 1
2 3
4
The Waterfall
1. Less stuff ✔ 2. Smaller stuff ✔ 3. Out of the way ✔ 4. Start early ✔
Waterfall ✓
Life after onload
Life after onload
1. Lazy-load 2. Pre-load 3. XHR 4. JavaScript optimizations 5. Rendering
Lazy-load
• bells & whistles
• badges & widgets
Preload
• to help next page’s waterfall
• img, CSS, JS, DNS lookups
XHR (Ajax)
• small – gzip, JSON
• less – Expires
• GET over POST
GET vs. POST for XHR
var url = 'test.php';
var request = new XMLHttpRequest();
request.open("POST", url, false);
// …
request.send('test=1');
GET vs. POST for XHR
JavaScript optimizations
• Number of DOM elements • DOM access • Event delegation
Touching the DOM
function foo() {
for (var count = 0; count < 1000; count++) {
document.body.innerHTML += 1;
}
}
Touching the DOM
function foo() {
var inner = '';
for (var count = 0; count < 1000; count++) {
inner += 1;
}
document.body.innerHTML += inner;
} 1000 times faster
Rendering
• CSS on top • No separate print CSS • CSS refactoring • No AlphaImageLoader • Expensive elements • No CSS expressions • Image dimensions
CSS early on • No separate print CSS file
/* screen styles */ #nav {...} .banner {...} /* print styles */ @media print { #nav {display: none} .banner {display: none;} }
CSS refactoring
• CSS tends to grow • Find unused selectors –
DustMeSelectors extension • Cleanup things like: #header #menu {...} div#menu {...} ul li {...}
No AlphaImageLoader #some‐element {
background: url(image.png); _background: none; _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader (src='image.png', sizingMethod='crop');
}
http://yuiblog.com/blog/2008/12/08/imageopt-5/
Expensive elements
• Avoid or limit <applet> <object> (IE) <iframe>
Life after onload
1. Lazy-load ✔ 2. Pre-load ✔ 3. XHR ✔ 4. JavaScript optimizations ✔
5. Rendering ✔
Life after onload ✓
YSlow 2.0
YSlow
• Firebug extension
• Why (is my page) slow?
http://developer.yahoo.com/yslow/
Yahoo! performance rules 1. Make Fewer HTTP Requests 2. Use a Content Delivery Network 3. Add an Expires or a Cache-Control Header 4. Gzip Components 5. Put Stylesheets at the Top 6. Put Scripts at the Bottom
7. Avoid CSS Expressions 8. Make JavaScript and CSS External 9. Reduce DNS Lookups 10. Minify JavaScript and CSS
11. Avoid Redirects 12. Remove Duplicate JS and CSS 13. Configure ETags 14. Make Ajax Cacheable
15. Flush the Buffer Early 16. Use GET for AJAX Requests 17. Post-load Components 18. Preload Components
19. Reduce the Number of DOM Elements 20. Split Components Across Domains 21. Minimize the Number of iframes
22. No 404s 23. Reduce Cookie Size 24. Use Cookie-free Domains for Components
25. Minimize DOM Access 26. Develop Smart Event Handlers 27. Choose <link> over @import 28. Avoid Filters
29. Optimize Images 30. Optimize CSS Sprites 31. Don't Scale Images in HTML 32. Make favicon.ico Small and Cacheable 33. Keep Components under 25K 34. Pack Components into a Multipart Document
YSlow 1.0. rules 1. Make Fewer HTTP Requests 2. Use a Content Delivery Network 3. Add an Expires or a Cache-Control Header 4. Gzip Components 5. Put Stylesheets at the Top 6. Put Scripts at the Bottom
7. Avoid CSS Expressions 8. Make JavaScript and CSS External 9. Reduce DNS Lookups 10. Minify JavaScript and CSS
11. Avoid Redirects 12. Remove Duplicate JS and CSS 13. Configure ETags 14. Make Ajax Cacheable
15. Flush the Buffer Early 16. Use GET for AJAX Requests 17. Post-load Components 18. Preload Components
19. Reduce the Number of DOM Elements 20. Split Components Across Domains 21. Minimize the Number of iframes
22. No 404s 23. Reduce Cookie Size 24. Use Cookie-free Domains for Components
25. Minimize DOM Access 26. Develop Smart Event Handlers 27. Choose <link> over @import 28. Avoid Filters
29. Optimize Images 30. Optimize CSS Sprites 31. Don't Scale Images in HTML 32. Make favicon.ico Small and Cacheable 33. Keep Components under 25K 34. Pack Components into a Multipart Document
YSlow 2.0. rules 1. Make Fewer HTTP Requests 2. Use a Content Delivery Network 3. Add an Expires or a Cache-Control Header 4. Gzip Components 5. Put Stylesheets at the Top 6. Put Scripts at the Bottom
7. Avoid CSS Expressions 8. Make JavaScript and CSS External 9. Reduce DNS Lookups 10. Minify JavaScript and CSS
11. Avoid Redirects 12. Remove Duplicate JS and CSS 13. Configure ETags 14. Make Ajax Cacheable
15. Flush the Buffer Early 16. Use GET for AJAX Requests 17. Post-load Components 18. Preload Components
19. Reduce the Number of DOM Elements 20. Split Components Across Domains 21. Minimize the Number of iframes
22. No 404s 23. Reduce Cookie Size 24. Use Cookie-free Domains for Components
25. Minimize DOM Access 26. Develop Smart Event Handlers 27. Choose <link> over @import 28. Avoid Filters
29. Optimize Images 30. Optimize CSS Sprites 31. Don't Scale Images in HTML 32. Make favicon.ico Small and Cacheable 33. Keep Components under 25K 34. Pack Components into a Multipart Document
YSlow 1.0. rule weights 1. Make Fewer HTTP Requests 8 2. Use a Content Delivery Network 6 3. Add an Expires or a Cache-Control Header 10
4. Gzip Components 8 5. Put Stylesheets at the Top 4 6. Put Scripts at the Bottom 4 7. Avoid CSS Expressions 3
8. Make JavaScript and CSS External 4 9. Reduce DNS Lookups 3 10. Minify JavaScript 4 11. Avoid Redirects 4
12. Remove Duplicate JS 4 13. Configure Etags 2
YSlow 2.0. rule weights 1. Make Fewer HTTP Requests 8
2. Use a Content Delivery Network 6
3. Add an Expires or a Cache-Control Header 10
4. Gzip Components 8
5. Put Stylesheets at the Top 4
6. Put Scripts at the Bottom 4
7. Avoid CSS Expressions 3
8. Make JavaScript and CSS External 4
9. Reduce DNS Lookups 3
10. Minify JavaScript and CSS 4
11. Avoid Redirects 4
12. Remove Duplicate JS and CSS 4
13. Configure Etags 2
14. Make Ajax Cacheable 4
16. Use GET for AJAX Requests 3
19. Reduce the Number of DOM Elements 3
22. No 404s 4
23. Reduce Cookie Size 3
24. Use Cookie-free Domains for Components 3
28. Avoid Filters 4
31. Don't Scale Images in HTML 3
32. Make favicon.ico Small and Cacheable 2
YSlow score
foreach rule total += rule score * rule weight end foreach score = total / sum of rule weights
YSlow letter score
• (A) 90 – 100 • (B) 80 – 89 • (C) 70 – 79 • (D) 60 – 69 • (E) 50 – 59 • (F) under 50
Custom rule 1. Add an Expires Header 2. Configure Etags
Score = 1100 / 12 = 91.66 (A) Note: max weight is 10, min rule score is 0
Rule Weight Rule score *
Expires header 10 100 (A) 1000
ETags 2 50 (E) 100
Total 12 1100
Rule scores
• Start from 100 • Penalty for every offence
Rule penalties 1. Make Fewer HTTP Requests 2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
# ok -points
JS 3 -4/off
CSS 2 -4/off
img 6 -3/off
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network 3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-10 points per
offending component
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add Expires Headers 4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
If expiration is less than
2 days subtract -11 points per
component
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components 5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-11 points per
offending component bigger than
500 bytes
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top 6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-10 points per
offending component
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom 7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-5 points per
offending component
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions 8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-2 points per
expression
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JS and CSS External 9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
Score is always n/a
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups 10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
4 domains ok
-5 points per domain
otherwise
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify 11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-10 points per
offender, including
inline
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects 12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-10 points per redirect
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. No Duplicates 13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-5 points per
duplicate JS or CSS
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure ETags 14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-11 points per
offending component
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable 16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-5 points per XHR
without at least 1 hour expiration
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests 19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-5 points per
non-GET XHR
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce # of DOM Elements 22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-10 points for every
250 elements over 900
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s 23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-5 points per
offending component
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size 24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-10 points per
component requested with over
1000 bytes of cookies
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Cookie-free Domains 28. Avoid Filters
31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-5 points per
component requested
with a cookie
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters 31. Don't Scale Images in HTML
32. Make favicon.ico Small and Cacheable
-5 points per offense
or -2 if using _filter hack
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML 32. Make favicon.ico Small and Cacheable
-5 points per scaled
down image
Rule penalties 1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires or a Cache-Control Header
4. Gzip Components
5. Put Stylesheets at the Top
6. Put Scripts at the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript and CSS
11. Avoid Redirects
12. Remove Duplicate JS and CSS
13. Configure Etags
14. Make Ajax Cacheable
16. Use GET for AJAX Requests
19. Reduce the Number of DOM Elements
22. No 404s
23. Reduce Cookie Size
24. Use Cookie-free Domains for Components
28. Avoid Filters
31. Don't Scale Images in HTML
32. Small cacheable favicon
-5 points if size is over 2000 bytes and -5 if no expiration
YSlow 2.0 ✓
Words of Wisdom
Performance matters
• It affects the user happiness • It affects the bottom line
Front-end
• That’s where most of the time is spent
It’s a marathon
• Not a sprint • Measure, monitor, link to business metrics • Bugs are expensive as the time passes, performance bugs even more so
What’s a low-hanging fruit?
• Takes one engineer • Takes 15 minutes
Steve Krug
For non-low-hanging fruits?
1. Pick 2 or 3 2. Fix, measure one by one 3. Come back and iterate
Thank you!
Stoyan Stefanov @stoyanstefanov http://www.phpied.com