Version 10, last updated by Andy Singleton at June 17, 2010 16:32 UTC
Client and javascript performance
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 %>