Windy cityrails performance_tuning

63
Rails Performance John McCaffrey Railsperformance.blogspot.com

description

Performance tuning presentation for Chicago Rails Conference. Focusing on Front end page improvements

Transcript of Windy cityrails performance_tuning

Page 1: Windy cityrails performance_tuning

Rails Performance

John McCaffreyRailsperformance.blogspot.com

Page 2: Windy cityrails performance_tuning

John McCaffrey: Its all about me

• Doing Rails since 2007• 3rd time presenting at WindyCityRails

o 2008: Advanced Firebug and JS unit testingo 2009: PDF Generation in Railso 2010: Rails Performance Tuning

• Addicted to Performance Tuning• railsperformance.blogspot.com

• Feedback: spkr8.com/t/4413  Or  bit.ly/PerfR8

    @J_McCaffrey

[email protected]

(the slides will be available, with tons of extra references)

Page 3: Windy cityrails performance_tuning

What are we gonna cover?

• Performance touches a lot of layers• We have a very diverse audience

Page 4: Windy cityrails performance_tuning

Measuring Page Load

Fixing page load problems

Analyzing Server Performance

Database issues

Ruby issues  Q&A

Starting off on the right foot

Page 5: Windy cityrails performance_tuning

It all started...

def organization_branches  get_organizations.flatten.uniq.select{|org| org.children.size > 0}end

def organization_leaves  get_organizations.flatten.uniq.select{|org| org.children.size == 0}end

def load_organizations    branches = current_user.organization_branches    leaves = current_user.organization_leaves    @branches = branches.to_json(:only => [:id, :name])    @leaves = leaves.to_json(:only => [:id, :name])    @organizations = @criteria.branch ?         leaves.collect {|o| [ o.name.titleize, o.id ] }.sort :         branches.collect {|o| [ o.name.titleize, o.id ] }.sort end

Page 6: Windy cityrails performance_tuning

def organization_branches  get_organizations.flatten.uniq.select{|org| org.children.size > 0}end

def organization_leaves  get_organizations.flatten.uniq.select{|org| org.children.size == 0}end

def load_organizations    branches = current_user.organization_branches    leaves = current_user.organization_leaves    @branches = branches.to_json(:only => [:id, :name])    @leaves = leaves.to_json(:only => [:id, :name])    @organizations = @criteria.branch ?         leaves.collect {|o| [ o.name.titleize, o.id ] }.sort :         branches.collect {|o| [ o.name.titleize, o.id ] }.sort end

It all started...

2811 queries!

Down to 17!!

Page 7: Windy cityrails performance_tuning

And then...

Invoicing issue:    If a customer resubmits an order with 2 years, they should be charged $9 but were only being charged $4.50

Do people ever calculate the ROI on software projects?

53626 * $4.50 = $241,317  (just in the last year)

Page 8: Windy cityrails performance_tuning

Our theme of the day: Leverage

Multiplying the power of your efforts, to achieve the greatest value

Page 9: Windy cityrails performance_tuning

Performance and Business metrics: Bing.com

Slower site = revenue drop 1 sec = 2.8% 2 sec = 4.3%

Page 10: Windy cityrails performance_tuning

Performance and Business metrics: Shopzilla.com

http://www.phpied.com/the-performance-business-pitch/

Went from 6 secdown to 1.2sec

Page 11: Windy cityrails performance_tuning

Fred Wilson: Speed is the most important feature

10 Golden Principles of Successful Web Apps   Fred Wilson, Venture Capitalist www.avc.com

1.Speed2. Instant Utility3. Software is media4. Less is More5. Make it programmable6. Make it personal7. Make it RESTful8. Discoverability9. Clean10.Playful

Page 12: Windy cityrails performance_tuning

OK, so where do we begin?

Page 13: Windy cityrails performance_tuning

Give yourself a fighting chance, make a plan

Alois Reitbauer, dynatrace

Anti-patterns1. Thinking Scalability something you just sprinkle on later2. Guessing, not testing3. Ad-hoc, unstructured4. Waiting until it hurts, not proactively planning5. Thinking that any early planning is Premature optimization

Video on wiki.parleys.com

Page 14: Windy cityrails performance_tuning

Premature optimization

"Premature optimization is the root of all evil"

-Donald Knuth

Page 15: Windy cityrails performance_tuning

Premature optimization

Some people really like Donald Knuth

Page 16: Windy cityrails performance_tuning

Premature optimization, with DJ DK

like, really, really like him

Page 17: Windy cityrails performance_tuning

Premature optimization

"Premature optimization is the root of all evil'

-Donald Knuth

"Quoting Knuth, as a way to avoid planning for performance issues, is a cop-out"@J_McCaffrey

"Don't waste time on making optimization changes until you KNOW they are necessary"

Page 18: Windy cityrails performance_tuning

If you can not measure it, you can not improve it.

— Lord Kelvin

Page 19: Windy cityrails performance_tuning

Let's do this the right way

Measure:• Understand the tools to use, at each layer, to measure

and monitor performance

Create repeatable tests:• Be able to invoke the system and easily test

Isolate your changes:• One thing at a time

That's it: Measure, Test, Isolated changes

Page 20: Windy cityrails performance_tuning

Terminology

 

Load:How much work is there?

 

Utilization:How much of the resources are in use?

 

Scalability:How well can we handle the load?

 

Throughput:How many tasks can be done per unit of time?

 

Concurrency:How many tasks can we do at once?

 

Capacity:How big can our throughput go before things fall apart?

Response time (avg)   ==   Latency

Requests per second   ==  Throughput

Page 21: Windy cityrails performance_tuning

Terminology

Performance:• The resources and Time for a single request• Measured in Response Time

Throughput:• The number requests that can be handled per/time• Measured in Requests per second

Scalability:• Ability to grow and handle more requests, without

significantly degrading the experience

Performance != Scalability

Page 22: Windy cityrails performance_tuning

Terminology

Let's say:        1 worker that can compute a job in .5 sec

    Throughput    = 2 jobs per sec             Latency     = .5 sec per job

Performance != Scalability

Adding more workers will not improve the latency

But not having enough workers can increase the response time, due to Queuing and delay

Page 23: Windy cityrails performance_tuning

There are performance opportunities at each layer

Page 24: Windy cityrails performance_tuning

Waterfall: Twitter.com

Waterfall

Total time: 3815 ms Dynamic generation: 250 ms (~7%) Static: 3369 ms (~89%) * Will not add to 100%

Page 25: Windy cityrails performance_tuning

Waterfall

When the backend is actually doing work

Page 26: Windy cityrails performance_tuning

Walmart: Waterfall

Waterfall

Total time: 5520 ms Dynamic generation: 388 ms (~7%) Static: 4580 ms (~82%)

Page 27: Windy cityrails performance_tuning

Firebug Netpanel

Simple and repeatable way to measure page load

Usually, less than 20% of the time is spent in fetching the HTML

So how do we optimize the other 80%?

Page 28: Windy cityrails performance_tuning

YSlow

• Created by Steve Souders• Observes the netpanel data, applies rules and gives you a

score.• Deep understanding of how the browser works• Its the best way to have a repeatable, measurement of

your  site's load performance

http://developer.yahoo.com/yslow/

Page 29: Windy cityrails performance_tuning

YSlow

1. 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• Avoid CSS Expressions• Make JavaScript and CSS External• Reduce DNS Lookups• Minify JavaScript and CSS• Avoid Redirects• Remove Duplicate Scripts• Configure ETags• Make AJAX Cacheable• 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

Page 30: Windy cityrails performance_tuning

Yslow: Created by Steve Souders

http://stevesouders.com/cuzillion/

Page 31: Windy cityrails performance_tuning

Google Page speed

• Similar to YSlow• includes paint events• separates out ads, trackers from your content• better recommendations and optimizations• 1 click to see optimized version of your files

http://code.google.com/speed/page-speed

Page 32: Windy cityrails performance_tuning

Google Page speed

Page 33: Windy cityrails performance_tuning

Google Page speed

Page 34: Windy cityrails performance_tuning

Make it repeatable

http://www.showslow.com/     track your site, or your competitors    will check every 24hrs for you

• webpagetest.org• gtmetrix.org• zoompf.com• loadimpact.com• gomez.com

Page 35: Windy cityrails performance_tuning

Summary

1. Page load is the place to start2. Read everything in the Yslow and PageSpeed rules3. Encourage other devs to play with YSlow, PageSpeed4. Show Webpagtest.org, and zoompf.com

5. Now that we have a way to measure page performance, we can think about making changes

Page 36: Windy cityrails performance_tuning

Measuring Page Load

Fixing page load problems

Analyzing Server Performance

Database issues

Ruby issues  Q&A

Starting off on the right foot

Page 37: Windy cityrails performance_tuning

Isn't everyone already doing this?

Analysis of the Alexa top 1000 sites found:

1. 42% don't gzip2. 44% have more than 2 css files3. 56% serve css from a cookied domain4. 62% don't minify5. 31% have more than 100k size css

Page 38: Windy cityrails performance_tuning

Compress with Gzip

1. Can save you 50% to 80% of your bandwidth2. Simplest performance improvement you can make3. Beware differences in browsers4. File types: html, js, css, xml, rss, txt, font, json

Probably the simplest and smartest thing you can do for your app!

Page 39: Windy cityrails performance_tuning

Combine and minify javascript and css

1. Jsmin or YUICompressor, or Sprockets2. Asset_packager3. javascript_include_tag :cache => "cache/all"

Load common js libraries from googlehttp://github.com/rpheath/google_ajax_libraries_api

Sprites and image optimzation1. spriteme.org2. JqueryUI already gives you sprited images

Image optimization1. Smush.it

Page 40: Windy cityrails performance_tuning

Expires and Browser Caching

Setting a far future expires tells the browser not to ask for the file

Using the query string lets us break the caching by having the browser ask for a new file

There is a problem with using a URL query string this way

http://blog.eliotsykes.com/2010/05/06/why-rails-asset-caching-is-broken/

Page 41: Windy cityrails performance_tuning

Rails Caching

Take your dynamic content, and make it static1. Page2. Action3. Fragment

Full length tutorials1. http://railslab.newrelic.com/2. http://railscasts.com/episodes?search=caching3. Greg Pollack Aloha on Rails http://vimeo.com/10860860

Page 42: Windy cityrails performance_tuning

Measuring Page Load

Fixing page load problems

Analyzing Server Performance

Database issues

Ruby issues  Q&A

Starting off on the right foot

Page 43: Windy cityrails performance_tuning

The Stack

You are here

Page 44: Windy cityrails performance_tuning

Request-log-analyzer

• http://github.com/wvanbergen/request-log-analyzer• Request distribution per hour• Most requested• HTTP methods• HTTP statuses returned• Rails action cache hits• Request duration• View rendering time• Database time• Process blockers• Failed requests

Page 45: Windy cityrails performance_tuning

Rack::Bug

Page 46: Windy cityrails performance_tuning

Rack::Bug

Page 47: Windy cityrails performance_tuning

Commercial tools

New Relic• Developer plugin is a good start• Free version doesn’t get you much• Bronze version with heroku

• Scoutapp.com• Similar to new Relic• Large selection of community plugins

Page 48: Windy cityrails performance_tuning

Testing tools

Apache bench ab -n 10 -c 2 http://www.somewhere.com/

Httperfhttperf --server localhost --port 3000 --uri / --num-conns 10000

Jmeteryes, its ugly, but its powerful

Page 49: Windy cityrails performance_tuning

Measuring Page Load

Fixing page load problems

Analyzing Server Performance

Database issues

Ruby issues  Q&A

Starting off on the right foot

Page 50: Windy cityrails performance_tuning

Database issues

Common database issues• Bad queries• Not utilizing explain• Inadequate indexes• N+1 queries• Selecting more data than is needed• Inconsistent queries for the same data

Page 51: Windy cityrails performance_tuning

Query_reviewer

Common database issues• Bad queries• Not utilizing explain

• http://github.com/dsboulder/query_reviewer • Runs explain on all of your queries, outputs to div in

page

Page 52: Windy cityrails performance_tuning

Rails_indexes

http://github.com/eladmeidar/rails_indexes

Foreign key indexs

• Columns that need to be sorted

• Lookup fields

• Columns that are used in a GROUP BY

• Rake tasks to find missing indexes.

New one I haven’t tried yet

http://github.com/samdanavia/ambitious_query_indexer

Page 53: Windy cityrails performance_tuning

Bullet plugin

Bullet plugin

• http://github.com/flyerhzm/bullet

Help you reduce the number of queries

with alerts (and growl).

Page 54: Windy cityrails performance_tuning

Slim_scrooge

Be more specific in your select• http://github.com/sdsykes/slim_scrooge• Instruments your code• Observes the usage pattern• Suggests/changes your select statement

• When invoked within the exact same context

Page 55: Windy cityrails performance_tuning

Ruby Issues

Most are due to memory problems• Slow GC• Not release references• Capturing scope

• Profiling will reveal what’s going on• http://guides.rubyonrails.org/performance_testing.html

If you want to learn everything there is to know about profiling • Aman Gupta• Joe Damato• http://timetobleed.com/ • http://memprof.com/ • They’ve already identified and fixed several memory leaks

Page 56: Windy cityrails performance_tuning

Ruby issues: Faster Ruby Libraries

C Extension++

• XML parser http://nokogiri.org/

• JSON parser http://github.com/brianmario/yajl-ruby/

• CSV parser http://www.toastyapps.com/excelsior/

• HTTP client http://github.com/pauldix/typhoeus

Date

http://github.com/jeremyevans/home_run

Page 57: Windy cityrails performance_tuning

Take home points

Performance• Performance affects the bottom line• The biggest performance win is usually in improving the load time• Continue to monitor and test your apps performance over time• Gzip, combine and minify to get a big boost• Lack of indexes is likely to be one of your biggest backend issues• Try to stay up to date with Gems, Plugins, and latest Rails• Upgrading to ruby 1.9 will give you a huge performance boost

Page 58: Windy cityrails performance_tuning

Links: great info on performance

Performance• Scaling Rails series http://railslab.newrelic.com/ • RailsCasts.com• Velocity Conference http://en.oreilly.com/velocity2010 • google io conference http://code.google.com/events/io/2010/ • dynatrace site http://ajax.dynatrace.com/pages/ • http://www.igvita.com/ • http://www.mysqlperformanceblog.com/

Page 59: Windy cityrails performance_tuning

Links

Questions?

@j_mccaffrey

[email protected]

Page 60: Windy cityrails performance_tuning

Beyond ySlow: improving page performance outside the initial load

MySql and Postgres Database tuning

Heroku: Building Scalable apps from the start

Tuning performance for Mobile devices

Performance Improvements coming in Rails 3, and 3.1

Speeding up your tests

Page 61: Windy cityrails performance_tuning

Wait, I made it through that?

Architectural musings

•Background long running tasks– Email, image processing, reports, feeds

•Leverage Rack, Sinatra or Padrino•Parallel processing, Event Machine•Learn from heroku, scalable from the start•Revaluate your cloudy-ness– Great RailsConf presentation by James Golick

Page 62: Windy cityrails performance_tuning

Wait, I made it through that?

Designing for performance• Watch how they really use it

• Multiple tabs?• Back and forth between list and detail view

• Great presentation at WindyCityRails2009 by David Eisinger • Optimizing perceived performance• Make it feel fast

Page 63: Windy cityrails performance_tuning

Questions for you

Architectural musings

• Moving to or already on Ruby 1.9?• Serving your content from a separate domain?– Cookieless?