"Never
underestimate the
        — CEO Eric Schmidt announcing
        Google Instant in September 2010
The Low-Hanging
      Fruit
    The 20 / 80 rule
I. Serve up lighter files

II. Trim back on HTTP

III. Keep things a-movin’
    (avoid blocking)
SERVE UP
Lighter Files
The HTTP Waterfall
Image Optimization
Images are often >50% of a page’s total weight!
Leaner JPEGs
Leaner JPEGs:
   Quality
Leaner JPEGs:
 Progressive
Leaner JPEGs:
  Metadata
Leaner JPEGs:
     Metadata
     command line ahoy!



> jpegtran -copy none -optimize
        src.jpg dest.jpg
Professional PNGs
Professional PNGs:
     bit depth
Professional PNGs:
       8bit
Professional PNGs:
 8bit alpha woes?
•8bit PNGs CAN have full alpha
 support!

•Use Adobe Fireworks instead
•Or run them through pngquant
Professional PNGs:
   PNGQUANT
     command line ahoy!




  > pngquant 256 whatever.png
Professional PNGs:
    PNGCRUSH
     command line ahoy!



 > pngcrush -rem alla -reduce
  -brute source.png dest.png
smush.it
That’s the URL!
animated GIFs are
      back
    gifsicle can help
Slimmer Text Fil
                         The Rudimentary Approach


•   class=“whatever”
    → class=whatever

•   http://www.utexas.edu/law/whatever.html
    → /law/whatever.html

•   <script type=“text/javascript”>
    → <script>

•   Use CSS shorthand!
Slimmer Text Fil
                  Minify your scripts and other text




jquery-1.6.3.js                          jquery-1.6.3.min.js
Slimmer Text Fil
            Minify your scripts and other text



• YUICompressor
• Google's Closure Compiler
• Dojo ShrinkSafe
• Packer
• JSMin
Slimmer Text Fil
                       Serious bandwidth savings with gzip


For Apache 2.x*:
<ifModule mod_deflate.c>

    AddOutputFilterByType DEFLATE text/html text/css application/x-javascript

</ifModule>




                                          * Note: don’t do this on Web Central…
Trim Back on
HTTP Requests
The Problem with
 HTTP Requests
 HTTP/1.1 specifies 2 maximum
 simultaneous TCP connections




    Source: HTTP/1.1 specification, RFC 2616 8.1.4
    http://www.w3.org/Protocols/rfc2616/rfc2616-
    sec8.html#sec8
The Problem with
 HTTP Requests
 HTTP/1.1 specifies 2 maximum
 simultaneous TCP connections

         (per domain)


    Source: HTTP/1.1 specification, RFC 2616 8.1.4
    http://www.w3.org/Protocols/rfc2616/rfc2616-
    sec8.html#sec8
HTTP Waterfall
     IE7




generated with http://
www.webpagetest.org/
HTTP Waterfall -
  Chrome 14
Remove Duplicates
                &
Fold print and
media query styles
Fold print and
   media query styles
<link rel="stylesheet" href="styles.css" />
<link rel="stylesheet" href="print.css" />
Fold print and
media query styles
/* Print styles in styles.css
@media print {
    body {
        background: #fff;
    }
}
CSS Image Sprites
CSS Image Sprites
use




      PS: Maybe use CSS opacity
      to cut down on the number
      of button states in an image
      sprite?
Data URIs
background-image: url("data:image/png;base64,xKfsiO…ssseAdd==");
Data URIs
Data URIs
•   Prevents the opening of an additional TCP request
Data URIs
•   Prevents the opening of an additional TCP request

•   Faster download than a separate image request
Data URIs
•   Prevents the opening of an additional TCP request

•   Faster download than a separate image request

•   Can be created on the fly in PHP with
    base64_encode()
Data URIs
•   Prevents the opening of an additional TCP request

•   Faster download than a separate image request

•   Can be created on the fly in PHP with
    base64_encode()

•   Are only cached if included inside of a stylesheet
    (not inline)
Data URIs
•   Prevents the opening of an additional TCP request

•   Faster download than a separate image request

•   Can be created on the fly in PHP with
    base64_encode()

•   Are only cached if included inside of a stylesheet
    (not inline)

•   ~30% larger than “real” image files
    (~2% if gzip is enabled)
Data URIs
•   Prevents the opening of an additional TCP request

•   Faster download than a separate image request

•   Can be created on the fly in PHP with
    base64_encode()

•   Are only cached if included inside of a stylesheet
    (not inline)

•   ~30% larger than “real” image files
    (~2% if gzip is enabled)

•   Wide browser support, but no IE 7 or older
    (and IE8 only supports up to 32KB of data)
Cache: Far-Future
    Expires
Cache: Far-Future
    Expires
Cache: Far-Future
        Expires
          Stick this in your .htaccess


<IfModule mod_expires.c>
ExpiresActive on
	 <FilesMatch ".(gif|jpg|png|js|css)$">
	    ExpiresDefault "access plus 5 years"
	 </FilesMatch>
</IfModule>
Cache: Far-Future
    Expires
Wait, why are they still seeing that version?!
Cache: Far-Future
         Expires
      Wait, why are they still seeing that version?!


• A good practice, but users might end up with old
  versions of styles and scripts…
Cache: Far-Future
         Expires
      Wait, why are they still seeing that version?!


• A good practice, but users might end up with old
  versions of styles and scripts…

• To force a fresh download you can rename the file
  (I hope you’ve got a CMS or build process that
   makes this easy!)
Cache: ETags
Cache: Disable
    ETags
 Another one for your .htaccess



 FileETag none
Cache: Disable
    ETags
 Another one for your .htaccess



 FileETag none


               Recommended by Microsoft and
               Apache!
               http://support.microsoft.com/?
               id=922733
               http://www.apacheweek.com/issues/
               02-0-18
Stay in Motion
(avoid resource
 blocking)
Blocking (IE7
  example)
What can cause
  blocking?
What can cause
           blocking? in
•   External scripts cause blocking,
    case of a document.write() and to
    ensure proper order of execution
What can cause
           blocking? in
•   External scripts cause blocking,
    case of a document.write() and to
    ensure proper order of execution

•Inline <script> can hang things up
What can cause
           blocking? in
•   External scripts cause blocking,
    case of a document.write() and to
    ensure proper order of execution

•Inline <script> can hang things up
•Scripts often don’t execute until
    stylesheets are finished downloading
What can cause
           blocking? in
•   External scripts cause blocking,
    case of a document.write() and to
    ensure proper order of execution

•Inline <script> can hang things up
•Scripts often don’t execute until
    stylesheets are finished downloading

•CSS @import causes blocking
    in older IE
What can cause
           blocking? in
•   External scripts cause blocking,
    case of a document.write() and to
    ensure proper order of execution

•Inline <script> can hang things up
•Scripts often don’t execute until
    stylesheets are finished downloading

•CSS @import causes blocking
    in older IE

•iframes can block onload from firing
Cuzillion
http://stevesouders.com/cuzillion/
How do we get
 around this?
How do we get
      around this?
•   Put stylesheets in the <head> using a
    <link> tag instead of @import
How do we get
      around this?
•   Put stylesheets in the <head> using a
    <link> tag instead of @import

•   Put your scripts as close to the
    </body> tag as possible (in most
    circumstances)
How do we get
      around this?
•   Put stylesheets in the <head> using a
    <link> tag instead of @import

•   Put your scripts as close to the
    </body> tag as possible (in most
    circumstances)

•   Use a script loader like LabJS or HeadJS
How do we get
      around this?
•   Put stylesheets in the <head> using a
    <link> tag instead of @import

•   Put your scripts as close to the
    </body> tag as possible (in most
    circumstances)

•   Use a script loader like LabJS or HeadJS

•   Use non-blocking script insertion
    techniques like XHR Injection **
Asynchronous
        Script Insertion
(function () {
    var ga   = document.createElement('script'),

        s     = document.getElementsByTagName('script')[0];

    ga.type   = 'text/javascript';
    ga.async = true;

    ga.src    = ('https:' === document.location.protocol ?
                'https://ssl' :
                'http://www') +
                '.google-analytics.com/ga.js';

    s.parentNode.insertBefore(ga, s);

}());
Forward-looking
  approaches
Forward-looking
     approaches
• <script  defer>
 (wide browser support, but
  execution order?)
Forward-looking
     approaches
• <script  defer>
 (wide browser support, but
  execution order?)

• <script async>
 (HTML5, widening support, but no IE)
Forward-looking
     approaches
• <script  defer>
 (wide browser support, but
  execution order?)

• <script async>
 (HTML5, widening support, but no IE)

• Web Workers
 (Multi-threaded JS processing! But no IE…)
DEMO

YSlow   PageSpeed
Going on an HTTP Diet: Front-End Web Performance

Going on an HTTP Diet: Front-End Web Performance

  • 2.
    "Never underestimate the — CEO Eric Schmidt announcing Google Instant in September 2010
  • 6.
    The Low-Hanging Fruit The 20 / 80 rule
  • 7.
    I. Serve uplighter files II. Trim back on HTTP III. Keep things a-movin’ (avoid blocking)
  • 8.
  • 9.
  • 10.
    Image Optimization Images areoften >50% of a page’s total weight!
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
    Leaner JPEGs: Metadata command line ahoy! > jpegtran -copy none -optimize src.jpg dest.jpg
  • 16.
  • 17.
  • 18.
  • 19.
    Professional PNGs: 8bitalpha woes? •8bit PNGs CAN have full alpha support! •Use Adobe Fireworks instead •Or run them through pngquant
  • 20.
    Professional PNGs: PNGQUANT command line ahoy! > pngquant 256 whatever.png
  • 21.
    Professional PNGs: PNGCRUSH command line ahoy! > pngcrush -rem alla -reduce -brute source.png dest.png
  • 22.
  • 23.
    animated GIFs are back gifsicle can help
  • 24.
    Slimmer Text Fil The Rudimentary Approach • class=“whatever” → class=whatever • http://www.utexas.edu/law/whatever.html → /law/whatever.html • <script type=“text/javascript”> → <script> • Use CSS shorthand!
  • 25.
    Slimmer Text Fil Minify your scripts and other text jquery-1.6.3.js jquery-1.6.3.min.js
  • 26.
    Slimmer Text Fil Minify your scripts and other text • YUICompressor • Google's Closure Compiler • Dojo ShrinkSafe • Packer • JSMin
  • 27.
    Slimmer Text Fil Serious bandwidth savings with gzip For Apache 2.x*: <ifModule mod_deflate.c> AddOutputFilterByType DEFLATE text/html text/css application/x-javascript </ifModule> * Note: don’t do this on Web Central…
  • 28.
  • 29.
    The Problem with HTTP Requests HTTP/1.1 specifies 2 maximum simultaneous TCP connections Source: HTTP/1.1 specification, RFC 2616 8.1.4 http://www.w3.org/Protocols/rfc2616/rfc2616- sec8.html#sec8
  • 30.
    The Problem with HTTP Requests HTTP/1.1 specifies 2 maximum simultaneous TCP connections (per domain) Source: HTTP/1.1 specification, RFC 2616 8.1.4 http://www.w3.org/Protocols/rfc2616/rfc2616- sec8.html#sec8
  • 31.
    HTTP Waterfall IE7 generated with http:// www.webpagetest.org/
  • 32.
  • 33.
  • 34.
  • 35.
    Fold print and media query styles <link rel="stylesheet" href="styles.css" /> <link rel="stylesheet" href="print.css" />
  • 36.
    Fold print and mediaquery styles /* Print styles in styles.css @media print { body { background: #fff; } }
  • 37.
  • 38.
  • 39.
    use PS: Maybe use CSS opacity to cut down on the number of button states in an image sprite?
  • 40.
  • 41.
  • 42.
    Data URIs • Prevents the opening of an additional TCP request
  • 43.
    Data URIs • Prevents the opening of an additional TCP request • Faster download than a separate image request
  • 44.
    Data URIs • Prevents the opening of an additional TCP request • Faster download than a separate image request • Can be created on the fly in PHP with base64_encode()
  • 45.
    Data URIs • Prevents the opening of an additional TCP request • Faster download than a separate image request • Can be created on the fly in PHP with base64_encode() • Are only cached if included inside of a stylesheet (not inline)
  • 46.
    Data URIs • Prevents the opening of an additional TCP request • Faster download than a separate image request • Can be created on the fly in PHP with base64_encode() • Are only cached if included inside of a stylesheet (not inline) • ~30% larger than “real” image files (~2% if gzip is enabled)
  • 47.
    Data URIs • Prevents the opening of an additional TCP request • Faster download than a separate image request • Can be created on the fly in PHP with base64_encode() • Are only cached if included inside of a stylesheet (not inline) • ~30% larger than “real” image files (~2% if gzip is enabled) • Wide browser support, but no IE 7 or older (and IE8 only supports up to 32KB of data)
  • 48.
  • 49.
  • 50.
    Cache: Far-Future Expires Stick this in your .htaccess <IfModule mod_expires.c> ExpiresActive on <FilesMatch ".(gif|jpg|png|js|css)$"> ExpiresDefault "access plus 5 years" </FilesMatch> </IfModule>
  • 51.
    Cache: Far-Future Expires Wait, why are they still seeing that version?!
  • 52.
    Cache: Far-Future Expires Wait, why are they still seeing that version?! • A good practice, but users might end up with old versions of styles and scripts…
  • 53.
    Cache: Far-Future Expires Wait, why are they still seeing that version?! • A good practice, but users might end up with old versions of styles and scripts… • To force a fresh download you can rename the file (I hope you’ve got a CMS or build process that makes this easy!)
  • 54.
  • 55.
    Cache: Disable ETags Another one for your .htaccess FileETag none
  • 56.
    Cache: Disable ETags Another one for your .htaccess FileETag none Recommended by Microsoft and Apache! http://support.microsoft.com/? id=922733 http://www.apacheweek.com/issues/ 02-0-18
  • 57.
    Stay in Motion (avoidresource blocking)
  • 58.
  • 59.
    What can cause blocking?
  • 60.
    What can cause blocking? in • External scripts cause blocking, case of a document.write() and to ensure proper order of execution
  • 61.
    What can cause blocking? in • External scripts cause blocking, case of a document.write() and to ensure proper order of execution •Inline <script> can hang things up
  • 62.
    What can cause blocking? in • External scripts cause blocking, case of a document.write() and to ensure proper order of execution •Inline <script> can hang things up •Scripts often don’t execute until stylesheets are finished downloading
  • 63.
    What can cause blocking? in • External scripts cause blocking, case of a document.write() and to ensure proper order of execution •Inline <script> can hang things up •Scripts often don’t execute until stylesheets are finished downloading •CSS @import causes blocking in older IE
  • 64.
    What can cause blocking? in • External scripts cause blocking, case of a document.write() and to ensure proper order of execution •Inline <script> can hang things up •Scripts often don’t execute until stylesheets are finished downloading •CSS @import causes blocking in older IE •iframes can block onload from firing
  • 65.
  • 66.
    How do weget around this?
  • 67.
    How do weget around this? • Put stylesheets in the <head> using a <link> tag instead of @import
  • 68.
    How do weget around this? • Put stylesheets in the <head> using a <link> tag instead of @import • Put your scripts as close to the </body> tag as possible (in most circumstances)
  • 69.
    How do weget around this? • Put stylesheets in the <head> using a <link> tag instead of @import • Put your scripts as close to the </body> tag as possible (in most circumstances) • Use a script loader like LabJS or HeadJS
  • 70.
    How do weget around this? • Put stylesheets in the <head> using a <link> tag instead of @import • Put your scripts as close to the </body> tag as possible (in most circumstances) • Use a script loader like LabJS or HeadJS • Use non-blocking script insertion techniques like XHR Injection **
  • 71.
    Asynchronous Script Insertion (function () { var ga = document.createElement('script'), s = document.getElementsByTagName('script')[0]; ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; s.parentNode.insertBefore(ga, s); }());
  • 72.
  • 73.
    Forward-looking approaches • <script defer> (wide browser support, but execution order?)
  • 74.
    Forward-looking approaches • <script defer> (wide browser support, but execution order?) • <script async> (HTML5, widening support, but no IE)
  • 75.
    Forward-looking approaches • <script defer> (wide browser support, but execution order?) • <script async> (HTML5, widening support, but no IE) • Web Workers (Multi-threaded JS processing! But no IE…)
  • 76.
    DEMO YSlow PageSpeed