Website
                         Performance Basics



http://www.flickr.com/photos/jerseygal2009/5762584119/   1
About

• Georg Kunz
• Working at
  www.local.ch
• Organizer of Ruby on Rails Usergroup Switzerland
  www.rubyonrails.ch


                        2
Agenda

• Whats wrong?
• Solutions
• Website Performance Analysis
• Rails Solution

                    3
Whats wrong?
<!DOCTYPE html>
<html lang='en'>
<head>
  <title>Jobs at local.ch</title>
  <link href="/styles/site.css" media="all" rel="stylesheet" type="text/css" />
  <link href="/styles/page.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
  <div id="header">
   <img alt="logo" src="/images/logo.gif"/>
  </div>
...


 • Many requests
 • Limited parallel downloads
 • No caching
 • File size
                                      4
Fewer Requests



      5
Combine CSS and
   JavaScript


       6
Images Sprites
          .image {
            background-position: -75px 0;
            width: 25px;
            height: 36px;
          }



      7
Inline Images in CSS

       background-image: url("data:image/
       png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEU
       gAAABcAAAAfCAIAAACDG8GaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAArp
       JREFUeNpi/Pr1669fv169evXu3bvv378zEA04OTmFhITExMTY2NgY379/f/
       36dUlJSVFRUW5ubuJNAVr/+vXr58+fa2pqsgBZQCMUFBQYSATcYABkAE1gAroF6Cpk6f
       +EALJioF6gCSw/fvzg4uKCCP379w/CmLn11e6zH289+f7kza+Fpcq
       +loJo1gBJJiYmIAnUCzSBhZGREVkOApbve3Pp/jcIe+rml8L8LFZavGg+AqqH6AWSTHBTgA6Bu3l/
       j6auIsiBLMyMT17/2nn6A6a/4A5HMQVN0f5uDaBBhUES6d6ie85/si++tu/CR6wBBDQBu48gYF
       +XOoQRaCVYu+hp4+KnX7799bEQQFOGzy3IQEKIZXaBvLU2T9mcx68+/
       MZ0CxPxCaQ5XtpIhTui9e7Hr3/RpJhISmmLyxW///
       q3cPcbikwBAmtt3u2nP1FqSoqnyMevfyg1RV2G4+8/
       hocvfyELskASMtaYxgOQ4whoAr70ghXcfPIDaK
       +cGCuxqQ4rmLvjjQAXM7JilFRHJDh69au7CR9a2mVhZmZGKxbwgITeRxxsjLHOAsiKgSaQ4KOGJS/
       O3/m+p0OJl5MJzUdEmfL83Z+mZS/vPf/
       ZmiAhzMuMphJkCp6Ydq26b6PNJSHIuubIRxYmhqpwMTtdbkxl+GLapfL+rac/bz/9KSbA4m/
       BVxUhisu9OH3kVHH/7nNQ6vz7778gD7OkMAse/6KYgmyQtRYXHxfzkze/X3/846jPFe/
       Mj2kKXCOKKUDv/fkDzWaNMaKYhT4agCcRUKoD1o8/f/
       4Ecvj4+FhYWIhJhCDLWViA6oFsoF6gCSzACuXLly/s7OwQg0jN4kC9QBOYeHh4Pn78+PbtW2CdT5J
       +oHqgLqBeoAmMwEr779+/

                                                                  ");
       QBLYYPj9+zfxprCysgKbDcCqGhhAAAEGAMqnupnRLnW1AAAAAElFTkSuQmCC

                 8
Parallel
                                                 Downloads

                                                 •   CDN
                                                 •   Additional hostnames




http://www.flickr.com/photos/spinnn/3493452660/        9
Headers
curl -I http://page/styles/site.css
Cache-Control: max-age=31536000, public
Expires: Sat, 08 Sep 2012 22:41:49 GMT




                            Caching
<!DOCTYPE html>
<html lang='en'>
<head>
  <title>Jobs at local.ch</title>
  <link href="/styles/site.css" media="all" rel="stylesheet" type="text/css" />
  <link href="/styles/page.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
  <div id="header">
   <img alt="logo" src="/images/logo.gif"/>
  </div>
...                                    10
Cache Busting

 <link href="/styles/site-8af74128f904600e41a6e39241464e03.css" media="all" rel="styleshe

 <img alt="logo" src="/images/logo-6b940dbed280e11507510cf378ac1d7f.gif"/>



http://www.flickr.com/photos/rhysasplundh/5201859761/   11
Minimize File Size




http://www.flickr.com/photos/ssanyal/347789298/
                                                 12
Compress Files
1.   Generate compressed files


           2.
                <LocationMatch	
  "^/assets/.*$">
                	
  	
  #	
  2	
  lines	
  to	
  serve	
  pre-­‐gzipped	
  version
                	
  	
  RewriteCond	
  %{REQUEST_FILENAME}.gz	
  -­‐s
                	
  	
  RewriteRule	
  ^(.+)	
  $1.gz	
  [L]
                	
  
                	
  	
  #	
  without	
  it,	
  Content-­‐Type	
  will	
  be	
  "application/x-­‐gzip"
                	
  	
  <FilesMatch	
  .*.css.gz>
                	
  	
  	
  	
  	
  	
  ForceType	
  text/css
                	
  	
  </FilesMatch>
                	
  
                	
  	
  <FilesMatch	
  .*.js.gz>
                	
  	
  	
  	
  	
  	
  ForceType	
  text/javascript
                	
  	
  </FilesMatch>
                </LocationMatch>

                                      13
Enable Compression
<IfModule mod_deflate.c>
  <IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
     SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)s,?s(gzip|deflate)?
     RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
    </IfModule>
  </IfModule>
  # html, txt, css, js, json, xml, htc:
  <IfModule filter_module>
    FilterDeclare   COMPRESS
    FilterProvider COMPRESS DEFLATE resp=Content-Type /text/(html|css|javascript|plain|x(ml|-component))/
    FilterProvider COMPRESS DEFLATE resp=Content-Type /application/(javascript|json|xml|x-javascript)/
    FilterChain     COMPRESS
    FilterProtocol COMPRESS change=yes;byteranges=no
  </IfModule>

  <IfModule !mod_filter.c>
    # Legacy versions of Apache
    AddOutputFilterByType DEFLATE text/html text/plain text/css application/json
    AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript
    AddOutputFilterByType DEFLATE text/xml application/xml text/x-component
  </IfModule>

  # webfonts and svg:
  <FilesMatch ".(ttf|otf|eot|svg)$" >
    SetOutputFilter DEFLATE
  </FilesMatch>
</IfModule>
                                                 14
YUI Compressor




         Minify CSS/JS
                      •   Closure Compiler
                      •   UglifyJS
                      •   JSMin
                      •   YUI Compressor
                 15
Check your page


       http://www.webpagetest.org/result/
110909_QY_22b0fa55b1bae814dd5af2579b041926/



                     16
Rails 3.1
Asset Pipeline




      17
Resources
• http://code.google.com/speed/page-speed/
  docs/rules_intro.htmls
• http://www.webpagetest.org



         By Steve Souders
                            18
BTW

• We’re hiring
• Our jobs are open source:
  http://github.com/local-ch/local-ch.github.com




• Looking forward to pull requests!
                             19
Questions



    20

Website Performance Basics

  • 1.
    Website Performance Basics http://www.flickr.com/photos/jerseygal2009/5762584119/ 1
  • 2.
    About • Georg Kunz •Working at www.local.ch • Organizer of Ruby on Rails Usergroup Switzerland www.rubyonrails.ch 2
  • 3.
    Agenda • Whats wrong? •Solutions • Website Performance Analysis • Rails Solution 3
  • 4.
    Whats wrong? <!DOCTYPE html> <htmllang='en'> <head>   <title>Jobs at local.ch</title>   <link href="/styles/site.css" media="all" rel="stylesheet" type="text/css" /> <link href="/styles/page.css" media="all" rel="stylesheet" type="text/css" /> </head> <body> <div id="header">    <img alt="logo" src="/images/logo.gif"/>   </div> ... • Many requests • Limited parallel downloads • No caching • File size 4
  • 5.
  • 6.
    Combine CSS and JavaScript 6
  • 7.
    Images Sprites .image {   background-position: -75px 0;   width: 25px;   height: 36px; } 7
  • 8.
    Inline Images inCSS background-image: url("data:image/ png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEU gAAABcAAAAfCAIAAACDG8GaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAArp JREFUeNpi/Pr1669fv169evXu3bvv378zEA04OTmFhITExMTY2NgY379/f/ 36dUlJSVFRUW5ubuJNAVr/+vXr58+fa2pqsgBZQCMUFBQYSATcYABkAE1gAroF6Cpk6f +EALJioF6gCSw/fvzg4uKCCP379w/CmLn11e6zH289+f7kza+Fpcq +loJo1gBJJiYmIAnUCzSBhZGREVkOApbve3Pp/jcIe+rml8L8LFZavGg+AqqH6AWSTHBTgA6Bu3l/ j6auIsiBLMyMT17/2nn6A6a/4A5HMQVN0f5uDaBBhUES6d6ie85/si++tu/CR6wBBDQBu48gYF +XOoQRaCVYu+hp4+KnX7799bEQQFOGzy3IQEKIZXaBvLU2T9mcx68+/ MZ0CxPxCaQ5XtpIhTui9e7Hr3/RpJhISmmLyxW/// q3cPcbikwBAmtt3u2nP1FqSoqnyMevfyg1RV2G4+8/ hocvfyELskASMtaYxgOQ4whoAr70ghXcfPIDaK +cGCuxqQ4rmLvjjQAXM7JilFRHJDh69au7CR9a2mVhZmZGKxbwgITeRxxsjLHOAsiKgSaQ4KOGJS/ O3/m+p0OJl5MJzUdEmfL83Z+mZS/vPf/ ZmiAhzMuMphJkCp6Ydq26b6PNJSHIuubIRxYmhqpwMTtdbkxl+GLapfL+rac/bz/9KSbA4m/ BVxUhisu9OH3kVHH/7nNQ6vz7778gD7OkMAse/6KYgmyQtRYXHxfzkze/X3/846jPFe/ Mj2kKXCOKKUDv/fkDzWaNMaKYhT4agCcRUKoD1o8/f/ 4Ecvj4+FhYWIhJhCDLWViA6oFsoF6gCSzACuXLly/s7OwQg0jN4kC9QBOYeHh4Pn78+PbtW2CdT5J +oHqgLqBeoAmMwEr779+/ "); QBLYYPj9+zfxprCysgKbDcCqGhhAAAEGAMqnupnRLnW1AAAAAElFTkSuQmCC 8
  • 9.
    Parallel Downloads • CDN • Additional hostnames http://www.flickr.com/photos/spinnn/3493452660/ 9
  • 10.
    Headers curl -I http://page/styles/site.css Cache-Control:max-age=31536000, public Expires: Sat, 08 Sep 2012 22:41:49 GMT Caching <!DOCTYPE html> <html lang='en'> <head>   <title>Jobs at local.ch</title>   <link href="/styles/site.css" media="all" rel="stylesheet" type="text/css" /> <link href="/styles/page.css" media="all" rel="stylesheet" type="text/css" /> </head> <body> <div id="header">    <img alt="logo" src="/images/logo.gif"/>   </div> ... 10
  • 11.
    Cache Busting <linkhref="/styles/site-8af74128f904600e41a6e39241464e03.css" media="all" rel="styleshe <img alt="logo" src="/images/logo-6b940dbed280e11507510cf378ac1d7f.gif"/> http://www.flickr.com/photos/rhysasplundh/5201859761/ 11
  • 12.
  • 13.
    Compress Files 1. Generate compressed files 2. <LocationMatch  "^/assets/.*$">    #  2  lines  to  serve  pre-­‐gzipped  version    RewriteCond  %{REQUEST_FILENAME}.gz  -­‐s    RewriteRule  ^(.+)  $1.gz  [L]      #  without  it,  Content-­‐Type  will  be  "application/x-­‐gzip"    <FilesMatch  .*.css.gz>            ForceType  text/css    </FilesMatch>      <FilesMatch  .*.js.gz>            ForceType  text/javascript    </FilesMatch> </LocationMatch> 13
  • 14.
    Enable Compression <IfModule mod_deflate.c> <IfModule mod_setenvif.c> <IfModule mod_headers.c> SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)s,?s(gzip|deflate)? RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding </IfModule> </IfModule> # html, txt, css, js, json, xml, htc: <IfModule filter_module> FilterDeclare COMPRESS FilterProvider COMPRESS DEFLATE resp=Content-Type /text/(html|css|javascript|plain|x(ml|-component))/ FilterProvider COMPRESS DEFLATE resp=Content-Type /application/(javascript|json|xml|x-javascript)/ FilterChain COMPRESS FilterProtocol COMPRESS change=yes;byteranges=no </IfModule> <IfModule !mod_filter.c> # Legacy versions of Apache AddOutputFilterByType DEFLATE text/html text/plain text/css application/json AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript AddOutputFilterByType DEFLATE text/xml application/xml text/x-component </IfModule> # webfonts and svg: <FilesMatch ".(ttf|otf|eot|svg)$" > SetOutputFilter DEFLATE </FilesMatch> </IfModule> 14
  • 15.
    YUI Compressor Minify CSS/JS • Closure Compiler • UglifyJS • JSMin • YUI Compressor 15
  • 16.
    Check your page http://www.webpagetest.org/result/ 110909_QY_22b0fa55b1bae814dd5af2579b041926/ 16
  • 17.
  • 18.
    Resources • http://code.google.com/speed/page-speed/ docs/rules_intro.htmls • http://www.webpagetest.org By Steve Souders 18
  • 19.
    BTW • We’re hiring •Our jobs are open source: http://github.com/local-ch/local-ch.github.com • Looking forward to pull requests! 19
  • 20.