interactive slides: bit.ly/faster-rails
pdf slides: bit.ly/faster-rails-pdf
Making the Web Fast(er)
one Rails page at a time
+Ilya Grigorik, @igrigorik
RailsConf 2012
+Ilya Grigorik, @igrigorik
RailsConf 2012
Browsing should be as simple and fast as turning a page in a magazine
Goal: make the entire web faster
| Delay | User reaction |
|---|---|
| 0-100ms | Instant |
| 0-300ms | Feels sluggish |
| 100-1000ms | Machine is working... |
| 1s+ | Mental context switch |
| 10s+ | I'll come back later... |

| Delay | User reaction |
|---|---|
| 0-100ms | Instant |
| 0-300ms | Feels sluggish |
| 300-1000ms | Machine is working... |
| 1s+ | Mental context switch |
| » we're here! « on average... | |
| 10s+ | I'll come back later... |
| Content Type | Avg # of Requests | Avg size |
|---|---|---|
| HTML | 8 | 44kB |
| Images | 53 | 635kB |
| Javascript | 14 | 189kB |
| CSS | 5 | 35kB |
Where is your bottleneck?




<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
cnn.com waterfall: blocking JS requests, missing assets, missing cache headers on images and JS. Plenty of room for improvement.
cnn.com timeline: evaluate every request, track JS execution time, style reflows, etc.
$> 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/chrome?q=railsconf&' + 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
// ...
TL;DR: You have no excuse.. all the tools are there!
Wonder how my page load time looks in IE {8,9,10} for a visitor from Singapore...
Test with various browsers, connection speeds, geo locations. Support for video capture, waterfall analysis, page speed optimization checks, and much more -- all, for free.

On-demand video + filmstrip view, tcpdump stats, HAR downloads, and more.
measures how quickly the page contents are visually populated
Plot "visual completeness" vs. time


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.


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.awesome-rails-app.com
DocumentRoot /apps/foo/public
PassengerEnabled on
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/faster-rails
Video: bit.ly/faster-rails-video