Proactive WPO
       @marcelduran
velocity@marcelduran.com
about:me
I'm not here
I'm from here on
V is for Vigilante


     http://usa-moscow.blogspot.com/2010/09/more-hot-water.html
Performance Radar
         http://www.flickr.com/photos/benfrantzdale/1056282822/
“if you can’t measure it, you can’t improve it”

                                 — Lord Kelvin
worst case: no instruments
             http://www.flickr.com/photos/timothyhackworth/753783003/
test
     build




             reactive
                          deploy



review



                  users
better case: RUM
          http://www.flickr.com/photos/pj/6116201547/
/lo
               b.com gnorm
         githu             al/
                               boo
                                   m
                                     er
                                       an
                                          g




Real User Measurements
                               http://lognormal.com/features/
test
     build




             reactive
                           deploy



monitor



                 users
YSlow manually
YSlow automation
         http://www.flickr.com/photos/snazzyguy/3381047684/
+
+
much better: RUM + YSlow (CI)
                    http://donq.com/recipes/rum-sour
test
     build



             proactive
                           wpo




                         deploy
monitor



                users
+174k users
         +3.3mi downloads
         Top 25 2bi add-ons downloaded


jul/07
~171k users



jul/07   mar/11
jul/07   mar/11   jun/11
~86k users




jul/07   mar/11   jun/11     aug/11
jul/07   mar/11   jun/11   aug/11




oct/11
jul/07            mar/11   jun/11   aug/11




oct/11   dec/11
first 24 hours
                                      437
                                          37
                           so far
                                         919
jul/07            mar/11        jun/11    aug/11
                                          77



oct/11   dec/11   feb/12
th
5 anniversary
        http://www.flickr.com/photos/spool32/5045502202
jul/07            mar/11   jun/11   aug/11




oct/11   dec/11   feb/12   apr/12
jul/07            mar/11   jun/11   aug/11




oct/11   dec/11   feb/12   apr/12   jun/12
YSlow Command Line
$ npm install yslow -g
$ yslow --help
Usage: yslow [options] [file ...]

Options:

 -h, --help                output usage information
 -V, --version             output the version number
 -i, --info <info>         specify the information to display/log
                           (basic|grade|stats|comps|all) [basic]
 -f, --format <format>     specify the output results format
                           (json|xml|plain) [json]
 -r, --ruleset <ruleset>   specify the YSlow performance ruleset to be used
                           (ydefault|yslow1|yblog) [ydefault]
 -b, --beacon <url>        specify an URL to log the results
 -d, --dict                include dictionary of results fields
 -v, --verbose             output beacon response information

Examples:

 yslow file.har
 yslow -i grade -f xml -b http://server.com/beacon file1.har file2.har
 yslow -info all --format plain /tmp/*.har
 yslow -i basic --rulseset yslow1 -d < file.har
 curl example.com/file.har | yslow -i grade -b http://server.com/beacon -v
{
    "log": {
      "version": "1.1",
      "pages": [
       {
         "startedDateTime": "2012-08-16T18:27:29.000+00:00",
         "id": "page_1_0",
         "pageTimings": {
           "onLoad": 13701,
         ...




                               HAR file
$   yslow file.har
$   yslow file1.har file2.har file3.har
$   yslow my-har-files/*.har
$   yslow < file.har
$   curl http://foo.com/file.har | yslow
-f, --format <format>   (json|xml|plain)
$ yslow foo.com.har
{ w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981 }

$ yslow --format xml foo.com.har
<?xml version="1.0" encoding="UTF-8"?>
<results>
  <w>98725</w>
  <o>89</o>
  <u>http://www.foo.com/</u>
  <r>9</r>
  <i>ydefault</i>
  <lt>981</lt>
</results>

$ yslow --format plain foo.com.har
size: 96.4K (98725 bytes)
overall score: B (89)
url: http://www.foo.com/
# of requests: 9
ruleset: ydefault
page load time: 981
-i, --info <info> (basic|grade|stats|comps|all)
$ yslow foo.com.har
{ w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981 }

$ yslow --info grade foo.com.har
{ w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981,
  g: { ynumreq: { score: 92, components: [] },
       ycdn:     { score: 80, components: ['a.com', 'b.com'] },
       ...
       yfavicon: { score: 100, components: [] }
     }
}

$ yslow --info stats foo.com.har
{ w: 98725, o: 89, u: 'foo.com', r: 9,   i: 'ydefault', lt: 981,
  stats: { doc:       { r: 1, w: 18419   },
           css:       { r: 2, w: 20951   },
           image:     { r: 3, w: 29553   },
           js:        { r: 2, w: 10852   },
           cssimage: { r: 1, w: 18950    }
     }
}
$ yslow --info comps foo.com.har
{ w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981,
  comps: [
  {type:'doc', url:'foo.com', size:1841, resp:41, gzip:613},
  {type:'css', url:'bar.css', size:3062, resp:98, gzip:989},
  ...
  {type:'js', url:'baz.js', size:2445, resp:86, gzip:834}
  ]
}
$ yslow --info all foo.com.har
{ w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981,
  g: {
    ynumreq: { score: 92, components: [] },
  ... }
  stats: {
    doc: { r: 1, w: 18419 }, css: { r: 2, w: 20951 },
  ... }
  comps: [
  {type:'doc', url:'foo.com', size:1841, resp:41, gzip:613},
  ... ]
}
-d, --dict
$ yslow -i basic --dict foo.com.har
{ w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981,
  dictionary: {
    w: 'size',
    o: 'overall score',
    u: 'url',
    r: 'total number of requests',
    i: 'id of the ruleset used',
    lt: 'page load time',
    grades: '100 >= A >= 90 > B >= 80 > C >= 70 > D >= 60
             > E >= 50 > F >= 0 > N/A = -1'
  }
}
-r, --ruleset <ruleset>
(ydefault | yslow1 | yblog)
Minimize HTTP Requests
Use a Content Delivery Network
Avoid empty src or href
Add an Expires or a Cache-Control Header
Gzip Components
Put StyleSheets at the Top
Put Scripts at the Bottom
Avoid CSS Expressions
Make JavaScript and CSS External
Reduce DNS Lookups
Minify JavaScript and CSS
                                              ydefault
Avoid Redirects
Remove Duplicate Scripts
                                           (aka YSlow V2)
Configure ETags
Make AJAX Cacheable                           23 rules
Use GET for AJAX Requests
Reduce the Number of DOM Elements
No 404s
Reduce Cookie Size
Use Cookie-Free Domains for Components
Avoid Filters
Do Not Scale Images in HTML
Make favicon.ico Small and Cacheable
Minimize HTTP Requests
Use a Content Delivery Network
Add an Expires or a Cache-Control Header
Gzip Components
Put StyleSheets at the Top
Put Scripts at the Bottom
                                            yslow1
Avoid CSS Expressions
Make JavaScript and CSS External
                                     (aka YSlow V1/classic)
Reduce DNS Lookups
Minify JavaScript and CSS                   13 rules
Avoid Redirects
Remove Duplicate Scripts
Configure ETags
Minimize HTTP Requests
Avoid empty src or href
Gzip Components
Put StyleSheets at the Top
Put Scripts at the Bottom
Avoid CSS Expressions                         yblog
Reduce DNS Lookups
Minify JavaScript and CSS
Avoid Redirects
                                       (aka small site/blog)
Remove Duplicate Scripts
Reduce the Number of DOM Elements
                                             15 rules
No 404s
Avoid Filters
Do Not Scale Images in HTML
Make favicon.ico Small and Cacheable
-b, --beacon <url>
   -v, --verbose
$ yslow --beacon http://server.com/ foo.com.har
{ w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981 }




$ yslow -b http://server.com/ --verbose foo.com.har
{ w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981,
  beacon: {
    status: 200,
    headers: {
       "content-type": 'text/html; charset=utf-8',
       "date": 'Thu, 02 Aug 2012 17:23:33 GMT',
       "content-length": '3',
       "connection": 'close'
    },
    body: 'okn'
  }
}
Case: Y! Continuous
   Deployment




before         after
No Performance Test Suite




  before          after
!
   O
 BO




YSlow for PhantomJS
           http://www.flickr.com/photos/pedroferrer/3615212504
$ phantomjs yslow.js http://yslow.org
-f, --format <format>
( json | xml | plain | tap | junit )
$ phantomjs yslow.js -i basic --format tap http://yslow.org
TAP version 13
1..1
ok 1 B (88) overall score


$ phantomjs yslow.js -i grade --format tap http://yslow.org
TAP version 13
1..24
ok 1 B (88) overall score
not ok 2 C (72) ynumreq: Make fewer HTTP requests
  ---
  message: This page has 7 external Javascript scripts
  ...
ok 3 C (70) ycdn: Use a Content Delivery Network (CDN)
  ---
  message: There are 3 static components not on CDN.
  offenders:
    - "yslow.org: 1 component, 8.0K (8.0K GZip)"
    - "fonts.googleapis.com: 1 component, 1.0K (1.0K GZip)"
    - "widgets.twimg.com: 1 component, 0.8K"
  ...
ok 4 A (100) yemptysrc: Avoid empty src or href
not ok 5 F (12) yexpires: Add Expires headers
  ---
  message: There are 5 static components without a far-future expiration date.
  offenders:
    - "http://yslow.org/stylesheets/styles-min.css"
...
$ phantomjs yslow.js -i basic --format junit http://yslow.org

<?xml version="1.0" encoding="UTF-8" ?>
<testsuites>
  <testsuite name="YSlow" tests="1" failures="1">
    <testcase name="overall score" status="C (79)">
      <failure/>
    </testcase>
  </testsuite>
</testsuites>
-t, --threshold <score>
( [0-100] | [A-F] | {json} )
         default: 80
-t B
-t 75
-t '{"overall": "C", "ycdn": "F"}'
-t '{"ycdn": "F", "yexpires": 75}'
-u, --ua "<user agent>"

e.g: -u "Mozilla/4.0 (compatible; MSIE 6)"
-vp, --viewport <WxH>

  e.g: -vp 640x960
-ch, --headers <JSON>

e.g: -ch '{"Cookie": "foo=bar"}'
-c, --console <level>
(0: none | 1: msg | 2: msg+line+source)
YSlow + CI = BFF
node.js server
remote HAR file
curl 'http://yslow.nodester.com/?har=http://server.com/foo.har'




local HAR file upload
curl http://yslow.nodester.com/ -F 'har=@localfile.har'




HAR {json} string
curl http://yslow.nodester.com/ -d 'har={"log":{"version":"1.1", ... }}'
+   +
curl "
http://yslow.nodester.com/
?har=http%3A%2F%2Fwww.webpagetest.org%2Fexport.php%3Ftest%3D120627_MC_5WD

&i=grade
&b=http%3A%2F%2Fwww.showslow.com%2Fbeacon%2Fyslow%2F
&v=1
"
A A A A ...
High Performance
+
          +
best: RUM + (YSlow + WPT) CI
                    http://donq.com/recipes/rum-sour/
WebPageTest
test
          build



                  proactive
                                      wpo



monitor
                                      perf



             users           deploy
prod   branch A branch B


                       ...
 performance boxes
branch A        branch B
prod
                   vs

        X+100ms         X-50ms

Xms
 branches comparison
http://marcelduran.com/webpagetest-api
github.com/marcelduran/webpagetest-api
+
+   vs
         +
谢谢
yslow.org
@yslow
/getyslow
      slides icons: http://www.iconfinder.com/

前瞻性Web性能优化pwpo

  • 1.
    Proactive WPO @marcelduran velocity@marcelduran.com
  • 2.
  • 3.
  • 4.
  • 5.
    V is forVigilante http://usa-moscow.blogspot.com/2010/09/more-hot-water.html
  • 6.
    Performance Radar http://www.flickr.com/photos/benfrantzdale/1056282822/
  • 7.
    “if you can’tmeasure it, you can’t improve it” — Lord Kelvin
  • 8.
    worst case: noinstruments http://www.flickr.com/photos/timothyhackworth/753783003/
  • 9.
    test build reactive deploy review users
  • 10.
    better case: RUM http://www.flickr.com/photos/pj/6116201547/
  • 11.
    /lo b.com gnorm githu al/ boo m er an g Real User Measurements http://lognormal.com/features/
  • 12.
    test build reactive deploy monitor users
  • 14.
  • 15.
    YSlow automation http://www.flickr.com/photos/snazzyguy/3381047684/
  • 16.
  • 17.
    + much better: RUM+ YSlow (CI) http://donq.com/recipes/rum-sour
  • 18.
    test build proactive wpo deploy monitor users
  • 19.
    +174k users +3.3mi downloads Top 25 2bi add-ons downloaded jul/07
  • 20.
  • 21.
    jul/07 mar/11 jun/11
  • 22.
    ~86k users jul/07 mar/11 jun/11 aug/11
  • 23.
    jul/07 mar/11 jun/11 aug/11 oct/11
  • 24.
    jul/07 mar/11 jun/11 aug/11 oct/11 dec/11
  • 25.
    first 24 hours 437 37 so far 919 jul/07 mar/11 jun/11 aug/11 77 oct/11 dec/11 feb/12
  • 26.
    th 5 anniversary http://www.flickr.com/photos/spool32/5045502202
  • 27.
    jul/07 mar/11 jun/11 aug/11 oct/11 dec/11 feb/12 apr/12
  • 28.
    jul/07 mar/11 jun/11 aug/11 oct/11 dec/11 feb/12 apr/12 jun/12
  • 29.
  • 30.
    $ npm installyslow -g
  • 31.
    $ yslow --help Usage:yslow [options] [file ...] Options: -h, --help output usage information -V, --version output the version number -i, --info <info> specify the information to display/log (basic|grade|stats|comps|all) [basic] -f, --format <format> specify the output results format (json|xml|plain) [json] -r, --ruleset <ruleset> specify the YSlow performance ruleset to be used (ydefault|yslow1|yblog) [ydefault] -b, --beacon <url> specify an URL to log the results -d, --dict include dictionary of results fields -v, --verbose output beacon response information Examples: yslow file.har yslow -i grade -f xml -b http://server.com/beacon file1.har file2.har yslow -info all --format plain /tmp/*.har yslow -i basic --rulseset yslow1 -d < file.har curl example.com/file.har | yslow -i grade -b http://server.com/beacon -v
  • 32.
    { "log": { "version": "1.1", "pages": [ { "startedDateTime": "2012-08-16T18:27:29.000+00:00", "id": "page_1_0", "pageTimings": { "onLoad": 13701, ... HAR file
  • 33.
    $ yslow file.har $ yslow file1.har file2.har file3.har $ yslow my-har-files/*.har $ yslow < file.har $ curl http://foo.com/file.har | yslow
  • 34.
    -f, --format <format> (json|xml|plain)
  • 35.
    $ yslow foo.com.har {w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981 } $ yslow --format xml foo.com.har <?xml version="1.0" encoding="UTF-8"?> <results> <w>98725</w> <o>89</o> <u>http://www.foo.com/</u> <r>9</r> <i>ydefault</i> <lt>981</lt> </results> $ yslow --format plain foo.com.har size: 96.4K (98725 bytes) overall score: B (89) url: http://www.foo.com/ # of requests: 9 ruleset: ydefault page load time: 981
  • 36.
    -i, --info <info>(basic|grade|stats|comps|all)
  • 37.
    $ yslow foo.com.har {w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981 } $ yslow --info grade foo.com.har { w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981, g: { ynumreq: { score: 92, components: [] }, ycdn: { score: 80, components: ['a.com', 'b.com'] }, ... yfavicon: { score: 100, components: [] } } } $ yslow --info stats foo.com.har { w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981, stats: { doc: { r: 1, w: 18419 }, css: { r: 2, w: 20951 }, image: { r: 3, w: 29553 }, js: { r: 2, w: 10852 }, cssimage: { r: 1, w: 18950 } } }
  • 38.
    $ yslow --infocomps foo.com.har { w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981, comps: [ {type:'doc', url:'foo.com', size:1841, resp:41, gzip:613}, {type:'css', url:'bar.css', size:3062, resp:98, gzip:989}, ... {type:'js', url:'baz.js', size:2445, resp:86, gzip:834} ] } $ yslow --info all foo.com.har { w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981, g: { ynumreq: { score: 92, components: [] }, ... } stats: { doc: { r: 1, w: 18419 }, css: { r: 2, w: 20951 }, ... } comps: [ {type:'doc', url:'foo.com', size:1841, resp:41, gzip:613}, ... ] }
  • 39.
  • 40.
    $ yslow -ibasic --dict foo.com.har { w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981, dictionary: { w: 'size', o: 'overall score', u: 'url', r: 'total number of requests', i: 'id of the ruleset used', lt: 'page load time', grades: '100 >= A >= 90 > B >= 80 > C >= 70 > D >= 60 > E >= 50 > F >= 0 > N/A = -1' } }
  • 41.
  • 42.
    Minimize HTTP Requests Usea Content Delivery Network Avoid empty src or href Add an Expires or a Cache-Control Header Gzip Components Put StyleSheets at the Top Put Scripts at the Bottom Avoid CSS Expressions Make JavaScript and CSS External Reduce DNS Lookups Minify JavaScript and CSS ydefault Avoid Redirects Remove Duplicate Scripts (aka YSlow V2) Configure ETags Make AJAX Cacheable 23 rules Use GET for AJAX Requests Reduce the Number of DOM Elements No 404s Reduce Cookie Size Use Cookie-Free Domains for Components Avoid Filters Do Not Scale Images in HTML Make favicon.ico Small and Cacheable
  • 43.
    Minimize HTTP Requests Usea Content Delivery Network Add an Expires or a Cache-Control Header Gzip Components Put StyleSheets at the Top Put Scripts at the Bottom yslow1 Avoid CSS Expressions Make JavaScript and CSS External (aka YSlow V1/classic) Reduce DNS Lookups Minify JavaScript and CSS 13 rules Avoid Redirects Remove Duplicate Scripts Configure ETags
  • 44.
    Minimize HTTP Requests Avoidempty src or href Gzip Components Put StyleSheets at the Top Put Scripts at the Bottom Avoid CSS Expressions yblog Reduce DNS Lookups Minify JavaScript and CSS Avoid Redirects (aka small site/blog) Remove Duplicate Scripts Reduce the Number of DOM Elements 15 rules No 404s Avoid Filters Do Not Scale Images in HTML Make favicon.ico Small and Cacheable
  • 45.
    -b, --beacon <url> -v, --verbose
  • 46.
    $ yslow --beaconhttp://server.com/ foo.com.har { w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981 } $ yslow -b http://server.com/ --verbose foo.com.har { w: 98725, o: 89, u: 'foo.com', r: 9, i: 'ydefault', lt: 981, beacon: { status: 200, headers: { "content-type": 'text/html; charset=utf-8', "date": 'Thu, 02 Aug 2012 17:23:33 GMT', "content-length": '3', "connection": 'close' }, body: 'okn' } }
  • 47.
    Case: Y! Continuous Deployment before after
  • 48.
    No Performance TestSuite before after
  • 49.
    ! O BO YSlow for PhantomJS http://www.flickr.com/photos/pedroferrer/3615212504
  • 50.
    $ phantomjs yslow.jshttp://yslow.org
  • 51.
    -f, --format <format> (json | xml | plain | tap | junit )
  • 52.
    $ phantomjs yslow.js-i basic --format tap http://yslow.org TAP version 13 1..1 ok 1 B (88) overall score $ phantomjs yslow.js -i grade --format tap http://yslow.org TAP version 13 1..24 ok 1 B (88) overall score not ok 2 C (72) ynumreq: Make fewer HTTP requests --- message: This page has 7 external Javascript scripts ... ok 3 C (70) ycdn: Use a Content Delivery Network (CDN) --- message: There are 3 static components not on CDN. offenders: - "yslow.org: 1 component, 8.0K (8.0K GZip)" - "fonts.googleapis.com: 1 component, 1.0K (1.0K GZip)" - "widgets.twimg.com: 1 component, 0.8K" ... ok 4 A (100) yemptysrc: Avoid empty src or href not ok 5 F (12) yexpires: Add Expires headers --- message: There are 5 static components without a far-future expiration date. offenders: - "http://yslow.org/stylesheets/styles-min.css" ...
  • 53.
    $ phantomjs yslow.js-i basic --format junit http://yslow.org <?xml version="1.0" encoding="UTF-8" ?> <testsuites> <testsuite name="YSlow" tests="1" failures="1"> <testcase name="overall score" status="C (79)"> <failure/> </testcase> </testsuite> </testsuites>
  • 54.
    -t, --threshold <score> ([0-100] | [A-F] | {json} ) default: 80
  • 55.
    -t B -t 75 -t'{"overall": "C", "ycdn": "F"}' -t '{"ycdn": "F", "yexpires": 75}'
  • 56.
    -u, --ua "<useragent>" e.g: -u "Mozilla/4.0 (compatible; MSIE 6)"
  • 57.
    -vp, --viewport <WxH> e.g: -vp 640x960
  • 58.
    -ch, --headers <JSON> e.g:-ch '{"Cookie": "foo=bar"}'
  • 59.
    -c, --console <level> (0:none | 1: msg | 2: msg+line+source)
  • 63.
  • 64.
  • 65.
    remote HAR file curl'http://yslow.nodester.com/?har=http://server.com/foo.har' local HAR file upload curl http://yslow.nodester.com/ -F 'har=@localfile.har' HAR {json} string curl http://yslow.nodester.com/ -d 'har={"log":{"version":"1.1", ... }}'
  • 66.
    + +
  • 67.
  • 68.
    A A AA ... High Performance
  • 69.
    + + best: RUM + (YSlow + WPT) CI http://donq.com/recipes/rum-sour/
  • 70.
  • 71.
    test build proactive wpo monitor perf users deploy
  • 72.
    prod branch A branch B ... performance boxes
  • 73.
    branch A branch B prod vs X+100ms X-50ms Xms branches comparison
  • 74.
  • 76.
  • 77.
    + + vs +
  • 78.
    谢谢 yslow.org @yslow /getyslow slides icons: http://www.iconfinder.com/