Make the entire web faster
| Delay | User reaction |
|---|---|
| 0-100 ms | Instant |
| 100-300 ms | Feels sluggish |
| 300-1000 ms | Machine is working... |
| 1 s+ | Mental context switch |
| 10 s+ | I'll come back later... |

| Content Type | Avg # of Requests | Avg size |
|---|---|---|
| HTML | 8 | 44kB |
| Images | 53 | 635kB |
| Javascript | 14 | 189kB |
| CSS | 5 | 35kB |

| DNS Resolution | 130ms average, see Google DNS |
| TCP handshake | TCP Fast Open & CWND proposals |
| Request pipelining | SPDY: multiplexing, compression, ... |
| Parsing & execution | You're running Chrome, right? |

Modest to no noticeable speedup after 5mbps! Errrrr.. why!?
Created via webpagetest.org: IE 8, from Tokyo... Yikes?
(faster) connectivity won't save us, better protocols can help, but...



<script> _gaq.push(['_setAccount','UA-XXXX-X']); _gaq.push(['_setSiteSpeedSampleRate', 100]); // #protip _gaq.push(['_trackPageview']); </script>
Google Analytics > Content > Site Speed


Content > Site Speed > Page Timings > Performance
Migrated site to new host, server stack, web layout, and using static generation. Result: noticeable shift in the user page load time distribution.
Content > Site Speed > Page Timings > Performance
Bimodal response time distribution?
Theory: user cache vs. database cache vs. full recompute
<script>
_gaq.push(['_trackTiming', 'category', 'label', time]);
_gaq.push(['_trackTiming', 'jQuery', 'Load library', 20]);
_gaq.push(['_trackTiming', 'slide', slideNum, timeOnSlide]);
// ^^^ win.
</script>
ResourceTiming interface to allow Javascript mechanisms to collect complete timing information related to resources on a document.
W3C draft / work in progress
cnn.com waterfall: blocking JS requests, missing assets, missing cache headers on images and JS. Plenty of room for improvement.
Question: what are the blue and red lines in the waterfall?
<script src="file-a.js"></script> <script src="file-b.js" defer></script> <script src="file-c.js" async></script>
<script src="file-a.js"></script> <script src="file-b.js" defer></script> <script src="file-c.js" async></script>
#protip: investigate a good script loader
cnn.com timeline: evaluate every request, track JS execution time, style reflows, etc.
60%+ of the weight of the page is images (on average)
#protip: automate it.
$> Google Chrome --remote-debugging-port=9222
$> curl localhost:9222/json
[ {
"devtoolsFrontendUrl": "/devtools/devtools.html?host=localhost:9222&page=1",
"faviconUrl": "",
"thumbnailUrl": "/thumb/chrome://newtab/",
"title": "New Tab",
"url": "chrome://newtab/",
"webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/1"
} ]
ws = Faye::WebSocket::Client.new(resp.first['webSocketDebuggerUrl'])
ws.onopen = lambda do |event|
ws.send JSON.dump({id: 1, method: 'Network.enable'})
ws.send JSON.dump({
id: 2,
method: 'Page.navigate',
params: {url: 'http://twitter.com/#!/search/html5?q=html5&' + rand(100).to_s}
})
end
ws.onmessage = lambda do |event|
p [:new_message, JSON.parse(event.data)]
end
"method":"Network.responseReceived",
"params":{
"type":"XHR",
"response":{
"url":"http://api.twitter.com/1/trends/available.json?lang=en",
"status":200,
"statusText":"OK",
"mimeType":"application/json",
"connectionReused":false,
"fromDiskCache":false,
"timing":{
"requestTime":1333830921.9814498,
"connectStart":1,
"receiveHeadersEnd":234
// ...
Connect your Android device via USB to the desktop & view and debug the code executing on the device
Google PageSpeed

require 'net/https'
require 'json'
uri = URI.parse('https://www.googleapis.com/pagespeedonline/v1/runPagespeed')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
params = { :key => 'API KEY', :url => 'http://railsconf2012.com/',
:strategy => 'desktop', :rules => '...' }
uri.query = URI.encode_www_form(params)
req = Net::HTTP::Get.new(uri.request_uri)
res = http.request(req)
jj JSON.parse(res.body)
API Documentation, widget examples, etc.

Goal: no surprises in the recommendations.

Open-source Apache module that automatically optimizes web pages and associated resources.
ModPagespeedCssInlineMaxBytes 2048 ModPagespeedImageInlineMaxBytes 2048 ModPagespeedCssImageInlineMaxBytes 2048 ModPagespeedJsInlineMaxBytes 2048 ModPagespeedCssOutlineMinBytes 3000 ModPagespeedJsOutlineMinBytes 3000 ModPagespeedRetainComments "[WILDCARD PATTERN]" ModPagespeedJpegRecompressionQuality -1 ModPagespeedImageLimitOptimizedPercent 100 ModPagespeedImageLimitResizeAreaPercent 100 ModPagespeedMaxInlinedPreviewImagesIndex 5 ModPagespeedMinImageSizeLowResolutionBytes 10240 // ...
<VirtualHost *:80>
ServerName www.your-awesome-html5-app.com
DocumentRoot /apps/foo/public
ModPagespeed on
/* ... */
</VirtualHost>
PageSpeed Service fetches content from your servers, rewrites the pages by applying web performance best practices and serves them to end users via Google's servers across the globe.
Setup:
Stay tuned for more...
+Ilya Grigorik, @igrigorik, igrigorik@google.com
Blog @ www.igvita.com
Slides: bit.ly/html5devconf-speed