Gerard Sychay php|works 2008 Atlanta, GA, USA Optimising The Front-End Using YSlow And PHP (In A Continuous Integration En...
Who am I? Gerard Sychay Technology Director Zipscene.com Cincinnati, OH, USA
Who am I? IRL Cool Web 2.0 Avatar
<ul><li>&quot;In sampling the top ten U.S. websites, all but one spend less than 20% of the total response time getting th...
Why Optimise Front-End?
Why Optimise Front-End?
<ul><li>Make fewer HTTP Requests </li></ul><ul><li>Use a Content Delivery Network </li></ul><ul><li>Add an Expires or a Ca...
<ul><li>Make fewer HTTP Requests </li></ul><ul><li>Use a Content Delivery Network </li></ul><ul><li>Add an Expires or a Ca...
Rule 1: Make Fewer HTTP Requests Instead of: <script type=&quot;text/javascript&quot; src=&quot;/javascript/foo.js&quot;><...
Rule 3: Add An Expires Header
Rule 3: Add An Expires Header
Rule 3: Add An Expires Header <Directory &quot;/var/www/html/css&quot;> ExpiresActive On ExpiresByType text/css &quot;acce...
Rule 3: Add An Expires Header
Rule 3: Add An Expires Header
<ul><li>So what if the file changes? </li></ul><ul><li><link ref=“stylesheet” type=“text/css” href=“main.css” /> </li></ul...
Rules 9,20,24: Domains
Rules 9,20,24: Domains &quot;Avoiding DNS lookups cuts response times, but reducing parallel downloads may increase respon...
<ul><li>http://static0.example.com </li></ul><ul><li>http://static1.example.com </li></ul><ul><li>... </li></ul>Rules 9,20...
Rules 10,29: Minify Javascript /*  Prototype JavaScript framework, version 1.5.1.1 *  (c) 2005-2007 Sam Stephenson * *  Pr...
<ul><li>Javascript </li></ul><ul><li>JSMin </li></ul><ul><li>Dojo Shrinksafe, YUI Compressor </li></ul><ul><li>Packer </li...
<ul><li>CSS </li></ul><ul><li>Pretty much just whitespace and comments </li></ul>Rules 10,29: Minify
<ul><li>Images </li></ul><ul><li>jpegtran </li></ul><ul><li>optipng </li></ul>Rules 10,29: Minify
Rule 12: Remove Duplicate Scripts
<ul><li>Let's Find Out... </li></ul>Can We Do All These At Once?
First Attempt: Template Function <html> <head> <?php  insert_js ('/javascript/foo.js', '/javascript/bar.js'); ?> <?php  in...
First Attempt: Template Function function insert_js($args) { static $alreadyLoaded = array(); $files = func_get_args(); //...
<ul><li>Instead of: </li></ul><ul><li><script type=“text/javascript” src=“/javascript/foo.js”></script> </li></ul><ul><li>...
<ul><li>Not bad, but… </li></ul><ul><li>Multiple  stat()  calls </li></ul><ul><li>What about CSS (e.g.  background-image: ...
<ul><li>PHP build system similar to  make </li></ul><ul><li>Port of  ant  to PHP </li></ul>Second Attempt: Phing
<ul><li>CSS </li></ul><ul><li>$pattern = ‘/(<link.*href=“[^”]*”.*/>s*)+/’; </li></ul><ul><li>$buffer = preg_replace_callba...
<ul><li>Images </li></ul><ul><li>$pattern = ‘/src=“([^”]*[gif|jpg|png])”’; </li></ul><ul><li>$buffer = preg_replace_callba...
<ul><li>Automatic front-end optimisations </li></ul><ul><li>Automatic unit testing with coverage </li></ul><ul><li>Automat...
<ul><li>Summary </li></ul><ul><li>Why the front-end is important </li></ul><ul><li>34  8 YSlow rules </li></ul><ul><li>Tem...
<ul><li>Links </li></ul><ul><li>34 Rules for High Perfomance Websites: </li></ul><ul><li>http://developer.yahoo.com/perfor...
<ul><li>Thanks! </li></ul><ul><li>Questions! </li></ul><ul><li>Comments! </li></ul><ul><li>[email_address] </li></ul><ul><...
<ul><li>© 2008. Some rights reserved.  </li></ul>
Upcoming SlideShare
Loading in...5
×

Front End Website Optimization

4,757

Published on

Yahoo has developed the de facto standard for building fast front-ends for websites. The bad news: you have to follow 34 rules to get there. The good news: I'll take a subset of those rules, explain them, and show how you can implement those rules in an automated fashion to minimize impact on developers and designers for your high-traffic website.

Published in: Technology
1 Comment
6 Likes
Statistics
Notes
No Downloads
Views
Total Views
4,757
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
128
Comments
1
Likes
6
Embeds 0
No embeds

No notes for slide

Front End Website Optimization

  1. 1. Gerard Sychay php|works 2008 Atlanta, GA, USA Optimising The Front-End Using YSlow And PHP (In A Continuous Integration Environment)
  2. 2. Who am I? Gerard Sychay Technology Director Zipscene.com Cincinnati, OH, USA
  3. 3. Who am I? IRL Cool Web 2.0 Avatar
  4. 4. <ul><li>&quot;In sampling the top ten U.S. websites, all but one spend less than 20% of the total response time getting the HTML document.&quot; </li></ul><ul><li>- http://developer.yahoo.com/performance/rules.html </li></ul>Why Optimise Front-End?
  5. 5. Why Optimise Front-End?
  6. 6. Why Optimise Front-End?
  7. 7. <ul><li>Make fewer HTTP Requests </li></ul><ul><li>Use a Content Delivery Network </li></ul><ul><li>Add an Expires or a Cache-Control Header </li></ul><ul><li>Gzip Components </li></ul><ul><li>Put Stylesheets at the Top </li></ul><ul><li>Put Scripts at the Bottom </li></ul><ul><li>Avoid CSS Expressions </li></ul><ul><li>Make JavaScript and CSS External </li></ul><ul><li>Reduce DNS Lookups </li></ul><ul><li>Minify JavaScript and CSS </li></ul><ul><li>Avoid Redirects </li></ul><ul><li>Remove Duplicate Scripts </li></ul><ul><li>Configure ETags </li></ul><ul><li>Make Ajax Cacheable </li></ul><ul><li>Flush the Buffer Early </li></ul><ul><li>Use GET for Ajax Requests </li></ul><ul><li>Post-load Components </li></ul>34 YSlow Rules <ul><li>Preload Components </li></ul><ul><li>Reduce the Number of DOM Elements </li></ul><ul><li>Split Components Across Domains </li></ul><ul><li>Minimize the Number of iframes </li></ul><ul><li>No 404s </li></ul><ul><li>Reduce Cookie Size </li></ul><ul><li>Use Cookie-free Domains for Components </li></ul><ul><li>Minimize DOM Access </li></ul><ul><li>Develop Smart Event Handlers </li></ul><ul><li>Choose <link> over @import </li></ul><ul><li>Avoid Filters </li></ul><ul><li>Optimize Images </li></ul><ul><li>Optimize CSS Sprites </li></ul><ul><li>Don’t Scale Images in HTML </li></ul><ul><li>Make favicon.ico Small and Cacheable </li></ul><ul><li>Keep Components under 25K </li></ul><ul><li>Pack Components into a Multipart Document </li></ul>
  8. 8. <ul><li>Make fewer HTTP Requests </li></ul><ul><li>Use a Content Delivery Network </li></ul><ul><li>Add an Expires or a Cache-Control Header </li></ul><ul><li>Gzip Components </li></ul><ul><li>Put Stylesheets at the Top </li></ul><ul><li>Put Scripts at the Bottom </li></ul><ul><li>Avoid CSS Expressions </li></ul><ul><li>Make JavaScript and CSS External </li></ul><ul><li>Reduce DNS Lookups </li></ul><ul><li>Minify JavaScript and CSS </li></ul><ul><li>Avoid Redirects </li></ul><ul><li>Remove Duplicate Scripts </li></ul><ul><li>Configure ETags </li></ul><ul><li>Make Ajax Cacheable </li></ul><ul><li>Flush the Buffer Early </li></ul><ul><li>Use GET for Ajax Requests </li></ul><ul><li>Post-load Components </li></ul>34 8 YSlow Rules <ul><li>Preload Components </li></ul><ul><li>Reduce the Number of DOM Elements </li></ul><ul><li>Split Components Across Domains </li></ul><ul><li>Minimize the Number of iframes </li></ul><ul><li>No 404s </li></ul><ul><li>Reduce Cookie Size </li></ul><ul><li>Use Cookie-free Domains for Components </li></ul><ul><li>Minimize DOM Access </li></ul><ul><li>Develop Smart Event Handlers </li></ul><ul><li>Choose <link> over @import </li></ul><ul><li>Avoid Filters </li></ul><ul><li>Optimize Images </li></ul><ul><li>Optimize CSS Sprites </li></ul><ul><li>Don’t Scale Images in HTML </li></ul><ul><li>Make favicon.ico Small and Cacheable </li></ul><ul><li>Keep Components under 25K </li></ul><ul><li>Pack Components into a Multipart Document </li></ul>
  9. 9. Rule 1: Make Fewer HTTP Requests Instead of: <script type=&quot;text/javascript&quot; src=&quot;/javascript/foo.js&quot;></script> <script type=&quot;text/javascript&quot; src=&quot;/javascript/bar.js&quot;></script> Can we make it: <script type=&quot;text/javascript&quot; src=&quot;/javascript/foobar.js&quot;></script> Instead of: <link rel=“stylesheet” type=“text/css” href=“/css/foo.css” /> <link rel=“stylesheet” type=“text/css” href=“/css/bar.css” /> Can we make it: <link rel=“stylesheet” type=“text/css” href=“/css/foobar.css” /> What about images?
  10. 10. Rule 3: Add An Expires Header
  11. 11. Rule 3: Add An Expires Header
  12. 12. Rule 3: Add An Expires Header <Directory &quot;/var/www/html/css&quot;> ExpiresActive On ExpiresByType text/css &quot;access plus 1 year” </Directory>
  13. 13. Rule 3: Add An Expires Header
  14. 14. Rule 3: Add An Expires Header
  15. 15. <ul><li>So what if the file changes? </li></ul><ul><li><link ref=“stylesheet” type=“text/css” href=“main.css” /> </li></ul><ul><li><link ref=“stylesheet” type=“text/css” href=“main.css?1207641610” /> </li></ul><ul><li><link ref=“stylesheet” type=“text/css” href=“main-1207641610.css” /> </li></ul>Rule 3: Add An Expires Header
  16. 16. Rules 9,20,24: Domains
  17. 17. Rules 9,20,24: Domains &quot;Avoiding DNS lookups cuts response times, but reducing parallel downloads may increase response times. [A] guideline is to split these components across at least two but no more than four hostnames .&quot;
  18. 18. <ul><li>http://static0.example.com </li></ul><ul><li>http://static1.example.com </li></ul><ul><li>... </li></ul>Rules 9,20,24: Domains <ul><li>BONUS! Optimise subdomains for static content </li></ul><ul><li>Cookies </li></ul><ul><li>HTTP Keep-Alive </li></ul><ul><li>AllowOverride </li></ul>
  19. 19. Rules 10,29: Minify Javascript /* Prototype JavaScript framework, version 1.5.1.1 * (c) 2005-2007 Sam Stephenson * * Prototype is freely distributable under the terms of an MIT-style license. * For details, see the Prototype web site: http://www.prototypejs.org/ * /*--------------------------------------------------------------------------*/ var Prototype = { Version: '1.5.1.1', Browser: { IE: !!(window.attachEvent && !window.opera), Opera: !!window.opera, WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1 },... var Prototype={Version:&quot;1.5.1.1&quot;,Browser:{IE:!!(window.attachEvent&&!window.opera),Opera:!!window.opera, WebKit:navigator.userAgent.indexOf(&quot;AppleWebKit/&quot;)>-1,Gecko:navigator.userAgent.indexOf(&quot;Gecko&quot;)>-1&& navigator.userAgent.indexOf(&quot;KHTML&quot;)==-1},BrowserFeatures:{XPath:!!document.evaluate,ElementExtensions:!! window.HTMLElement,SpecificElementExtensions:(document.createElement(&quot;div&quot;).__proto__!==document.createElement(&quot;form&quot;).__proto__)}...
  20. 20. <ul><li>Javascript </li></ul><ul><li>JSMin </li></ul><ul><li>Dojo Shrinksafe, YUI Compressor </li></ul><ul><li>Packer </li></ul>Rules 10,29: Minify
  21. 21. <ul><li>CSS </li></ul><ul><li>Pretty much just whitespace and comments </li></ul>Rules 10,29: Minify
  22. 22. <ul><li>Images </li></ul><ul><li>jpegtran </li></ul><ul><li>optipng </li></ul>Rules 10,29: Minify
  23. 23. Rule 12: Remove Duplicate Scripts
  24. 24. <ul><li>Let's Find Out... </li></ul>Can We Do All These At Once?
  25. 25. First Attempt: Template Function <html> <head> <?php insert_js ('/javascript/foo.js', '/javascript/bar.js'); ?> <?php insert_css ('/css/foo.css', '/css/bar.css'); ?> </head> <body> <?php insert_img ('/images/foo.jpg'); ?> ...
  26. 26. First Attempt: Template Function function insert_js($args) { static $alreadyLoaded = array(); $files = func_get_args(); // get array of javascript files $bundlefile = str_replace('/javascript/', '', join('', $files)); $bundlefile = str_replace('.js', '', $bundlefile); $buffer = ''; $latest = 0; foreach ($files as $file) { if (isset($alreadyLoaded[$file])) continue; else $alreadyLoaded[$file] = true; $mtime = filemtime(APP_ROOT . $file); if ($mtime > $latest) $latest = $mtime; // get the latest modification time $minified = YuiCompress::compress(APP_ROOT . $file); // minify content $buffer .= &quot;$minified &quot;; } $handle = fopen(APP_ROOT . &quot;/cache/$bundlefile-$latest.js&quot;, 'w'); // open bundle fwrite($handle, $buffer); // write minified content to bundle file fclose($handle); $twoBitValue = 0x3 & crc32(&quot;$bundlefile.js&quot;); // generate subdomain $path = &quot;http://static{$twoBitValue}.example.com/cache/$bundlefile-$latest.js&quot;; echo &quot;<script type=&quot;text/javascript&quot; src=&quot;$path&quot;></script>&quot;; } <ul><li>Combine </li></ul><ul><li>Expires </li></ul><ul><li>Subdomain </li></ul><ul><li>Minify </li></ul><ul><li>Remove duplicate </li></ul>
  27. 27. <ul><li>Instead of: </li></ul><ul><li><script type=“text/javascript” src=“/javascript/foo.js”></script> </li></ul><ul><li><script type=“text/javascript” src=“/javascript/bar.js”></script> </li></ul><ul><li>We now have: </li></ul><ul><li><script type=“text/javascript” src=“http://static2.example.com/cache/foobar-1207762384.js”> </li></ul><ul><li></script> </li></ul>First Attempt: Template Function
  28. 28. <ul><li>Not bad, but… </li></ul><ul><li>Multiple stat() calls </li></ul><ul><li>What about CSS (e.g. background-image: url(‘…’) )? </li></ul><ul><li>AND IT MAKES THIS GUY SAD </li></ul>First Attempt: Template Function
  29. 29. <ul><li>PHP build system similar to make </li></ul><ul><li>Port of ant to PHP </li></ul>Second Attempt: Phing
  30. 30. <ul><li>CSS </li></ul><ul><li>$pattern = ‘/(<link.*href=“[^”]*”.*/>s*)+/’; </li></ul><ul><li>$buffer = preg_replace_callback($pattern, “insert_css”, $buffer); </li></ul><ul><li>Javascript </li></ul><ul><li>$pattern = ‘/(<script.*src=“[^”]*”.”></script>s*)+/’; </li></ul><ul><li>$buffer = preg_replace_callback($pattern, “insert_js”, $buffer); </li></ul>Second Attempt: Phing
  31. 31. <ul><li>Images </li></ul><ul><li>$pattern = ‘/src=“([^”]*[gif|jpg|png])”’; </li></ul><ul><li>$buffer = preg_replace_callback($pattern, “insert_img”, $buffer); </li></ul><ul><li>$pattern = ‘/url(‘?.*[gif|jpg|png]’?)/”; </li></ul><ul><li>$buffer = preg_replace_callback($pattern, “insert_cssimg”, $buffer); </li></ul>Second Attempt: Phing
  32. 32. <ul><li>Automatic front-end optimisations </li></ul><ul><li>Automatic unit testing with coverage </li></ul><ul><li>Automatic syntax checking (with `php -l` ) </li></ul><ul><li>Automatic standards checking (with PHPCodeSniffer) </li></ul><ul><li>Automatic deployment to integration </li></ul><ul><li>Automatic deployment to any environment </li></ul><ul><li>History of builds </li></ul>Beyond Phing: Continuous Integration
  33. 33. <ul><li>Summary </li></ul><ul><li>Why the front-end is important </li></ul><ul><li>34 8 YSlow rules </li></ul><ul><li>Template functions </li></ul><ul><li>Continuous deployment </li></ul>Fin
  34. 34. <ul><li>Links </li></ul><ul><li>34 Rules for High Perfomance Websites: </li></ul><ul><li>http://developer.yahoo.com/performance/rules.html </li></ul><ul><li>YSlow homepage: </li></ul><ul><li>http://developer.yahoo.com/yslow/ </li></ul><ul><li>Cal Henderson Flickr article: </li></ul><ul><li>http://www.thinkvitamin.com/features/webapps/serving-javascript-fast </li></ul><ul><li>Sitepoint article: </li></ul><ul><li>http://www.sitepoint.com/article/web-site-optimization-steps/ </li></ul>Fin
  35. 35. <ul><li>Thanks! </li></ul><ul><li>Questions! </li></ul><ul><li>Comments! </li></ul><ul><li>[email_address] </li></ul><ul><li>twitter.com/hellogerard </li></ul><ul><li>straylightrun.net </li></ul>Fin
  36. 36. <ul><li>© 2008. Some rights reserved. </li></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×