Version 10, last updated by Andy Singleton at June 17, 2010 16:32 UTC

Links:

http://asciicasts.com/tags/performance

http://asciicasts.com/episodes/181-include-vs-joins

http://blog.envylabs.com/2009/11/scaling-rails/

http://railslab.newrelic.com/scaling-rails

http://support.newrelic.com/faqs/docs/developer-mode

http://support.newrelic.com/faqs/docs/ruby-agent-installation

Googles PageSpeed firefox plugin, think YSlow on steroids

 

Views

When addressing performance, be especially concerned with loops and frequently called partials. 

If you find that you are doing sql calls in loops, consider if it might be possible to prefetch that data. Either by storing it in a hash or by using :include

Painless

Convert static images to css classes:

- <%= link_to_remote_redbox(
 image_tag("/images/ico-add.png", :title => "Add Ticket"),
 :url => add_story_space_ticket_path(@space, "mock", :is_ticket => true, :milestone_id => nil),
 :method => :get, :complete =>; "addSimpleWikiToolbar();")  %>

+ <%= link_to_remote_redbox(
 "<span class='icons icon-add' title ='Add Ticket'></span>",
 :url => add_story_space_ticket_path(@space, "mock", :is_ticket => true, :milestone_id => nil), 
 :method => :get, :complete => "addSimpleWikiToolbar();")  %>

This can reduce the number of http requests drastically and also avoids the performance penalty of image_tag

Advanced:

Replace dynamic script generation with reusable javascript functions

<%= link_to_remote_redbox(
 "<span class='icons icon-add' title ='Add Ticket'></span>", 
 :url => add_story_space_ticket_path(@space, "mock", :is_ticket => true, :milestone_id => nil), 
 :method => :get, 
 :complete => "addSimpleWikiToolbar();")  %>

In this example the call to link_to_remote_redbox() will insert the following inline html each time:

<span id="hidden_content_spacesbreakouttickets4039add_story" style="display: none;"/>;
<a onclick="new Ajax.Updater(
 'hidden_content_spacesbreakouttickets4039add_story', '/spaces/breakout/tickets/4039/add_story', 
  {asynchronous:true, evalScripts:true, method:'get', 
  onComplete:function(request){RedBox.addHiddenContent(
  'hidden_content_spacesbreakouttickets4039add_story');
   addSimpleWikiToolbar();}, 
  onLoading:function(request){RedBox.loading(); }}); return false;" href="#">

This slows down page loading but also slows down the view generation significantly due to redbox overhead.

Where appropriate this can be improved by inserting the following javascript and html once:

<div id="hidden_content_spaces" style="display:none"/>
function storyAddChild(ticket_id){
 new Ajax.Updater('hidden_content_spaces',
  '/spaces/'+Breakout.space_wiki_name+'/tickets/'+ticket_id+'/add_story',
  {asynchronous:true, evalScripts:true, method:'get',
     onComplete:function(request){RedBox.addHiddenContent('hidden_content_spaces');addSimpleWikiToolbar();},
     onLoading:function(request){RedBox.loading(); }
 });
}

and replacing the redbox call with:

<a onclick="storyAddChild('<%=ticket.number %>');return false;" class='icons icon-add' title='Add Child Ticket' href="#"/>

Avoid frequent context switches:

Prefer:

<%= if has_edit_permissions
 foo()
 bar()
end %>

Over:

 <%= foo() if has_edit_permissions %>
 <%= bar() if has_edit_permissions %>