Benchmarking and Refactoring the content_for View Helper

Episode #90 by Teacher's Avatar David Kimura

Summary

In a recent blog post, we looked into the content_for view helper to render breadcrumbs. Once we got the feature working, it's time to refactor the feature to lower technical debt.
rails performance benchmark refactor 7:11

Resources

Summary

# Terminal
rails generate performance_test homepage

# Gemfile
gem 'rails-perftest'
gem 'ruby-prof'

# application.html.erb
    <%= benchmark 'Breadcrumbs' do %>
      <%= render 'layouts/breadcrumbs' %>
    <% end %>

# test/performance/homepage_test.rb
require 'test_helper'
require 'rails/performance_test_help'

class HomepageTest < ActionDispatch::PerformanceTest
  self.profile_options = { runs: 500, metrics: [:wall_time, :memory], output: 'tmp/performance' }

  test "homepage" do
    get '/'
  end
end

# Terminal
rails test:performance

# _breadcrumbs.html.erb
# Filed removed since it's no longer needed.

# <%= content_tag :nav, class: 'breadcrumb' do %>
#   <%= link_to 'Home', root_path, class: 'breadcrumb-item' %>
#   <% breadcrumbs = JSON.parse(sanitize yield(:breadcrumbs)) if content_for?(:breadcrumbs) %>
#   <% breadcrumbs.each do |breadcrumb| %>
#     <% case breadcrumb.class.to_s %>
#     <% when 'Array' %>
#       <% string, link = breadcrumb %>
#       <%= link_to string, link, class: "breadcrumb-item #{breadcrumb.equal?(breadcrumbs.last) ? 'active' : nil}" %>
#     <% when 'String' %>
#       <%= content_tag :span, breadcrumb, class: "breadcrumb-item #{breadcrumb.equal?(breadcrumbs.last) ? 'active' : nil}" %>
#     <% end %>
#   <% end if content_for?(:breadcrumbs) %>
# <% end %>

# <%= yield :breadcrumbs %>

# index.html.erb
<%= content_for :breadcrumbs, breadcrumbs_helper(['Users', ['John Doe', 'URL_STRING'],'Static', 'Edit']) %>

# application_helper.rb
  def breadcrumbs_helper(breadcrumbs)
    html = ''
    html << "<nav class='breadcrumb'>"
    html << link_to('Home', root_path, class: 'breadcrumb-item')
    breadcrumbs.each do |item|
      case item.class.to_s
      when 'Array'
        string, link = item
        html << link_to(string, link, class: "breadcrumb-item #{item.equal?(breadcrumbs.last) ? 'active' : nil}")
      when 'String'
        html << content_tag(:span, item, class: "breadcrumb-item #{item.equal?(breadcrumbs.last) ? 'active' : nil}")
      end
    end
    html << '</nav>'
    html.html_safe
  end

# application.html.erb
<%= yield :breadcrumbs %>
<%= yield %>