Rails HTML Fragment Caching with Cache Rocket

Post on 08-Jul-2015

3.839 views 1 download

Tags:

description

Key-based fragment caching in Rails is a great way to improve server-side response times. The cache_rocket gem provides a few simple techniques to make html rendering even faster and more efficient. Discussed: usage, performance, and trade-offs of key-based caching techniques.

Transcript of Rails HTML Fragment Caching with Cache Rocket

and����������� ������������������  lovekey-based����������� ������������������  HTML����������� ������������������  fragment����������� ������������������  caching

How����������� ������������������  I����������� ������������������  learnedto����������� ������������������  stop����������� ������������������  worrying

TEE PARHAM@teeparham

Do����������� ������������������  not����������� ������������������  expire����������� ������������������  keys

1

Model����������� ������������������  associationsgovernexpiry

2

3 Nestedcachingis����������� ������������������  best

class Project has_many :todo_lists

class TodoList belongs_to :project, touch: true has_many :todos

class Todo belongs_to :todo_list, touch: true

> todo = Todo.first => #<Todo id: 1, updated_at: "2013-11-19 00:24:01"> > todo.cache_key => "todos/1-20131119002401851149000"

cache_key

> todo = Todo.first => #<Todo id: 1, updated_at: "2013-11-19 00:24:01"> > todo.cache_key => "todos/1-20131119002401851149000"

cache_key

Project

Todo

TodoList

> todo.cache_key=> "todos/1-20131119002401851149000"

> cache(‘todo_item’, todo)=> "todo_item/todos/1-20131119002401851149000"

view����������� ������������������  keys

- @projects.each do |project| - cache [‘project’, project] do ...project... - project.todo_lists.each do |todo_list| - cache [‘todo_list’, todo_list] do ...todo_list... - todo_list.todos.each do |todo| - cache [‘todo’, todo] do ...todo...

YO����������� ������������������  DAWG

has_many����������� ������������������  ����������� ������������������  :arrows

adifferenthammer

User*

City

User

Idea**

YO����������� ������������������  DAWG?*

.stream-item .item-rail .avatar-stream = avatar(idea.user) .mobile-meta.show-for-small Suggested by #{user_link(idea.user)} %br/ = l idea.created_at, format: :short_year .item-pointer .item-content .bubble-stream{class: activity_class(idea)} .item-main{class: ('has-media' if idea.has_stream_media?)} - if idea.has_stream_media? .stream-media = link_to stream_image(idea), idea_path(idea) - if idea.stream_media_video? = link_to "&#9654;".html_safe, idea_path(idea) .text .text-body = want_link(idea) .sub %span.actions = solution_count(idea) = me_too_link(idea)

- cache [‘stream’, idea, current_user] do .all-the-codez = me_too_link(idea)

hit����������� ������������������  rate?

key:����������� ������������������  [idea,����������� ������������������  user]

hit����������� ������������������  rate:����������� ������������������  1����������� ������������������  /����������� ������������������  Idea.count*User.count

hit����������� ������������������  rate

why����������� ������������������  hit����������� ������������������  rate����������� ������������������  matters

= render_cached 'stream/idea', idea: idea, replace: {me_too_link: me_too_link(idea)}

- cache [‘stream’, idea] do .all-the-codez = cache_replace_key :me_too_link

cache_rocket

stream/_idea.html.haml

:me_too_link

cache [‘stream’, idea]

<div class="stream-item"> <div class="item-rail"> <div class="avatar-stream"> <a href="/neighbors/abarad" class="avatar-lnk" data-username="abarad"><img alt="Amy Barad" height="65" src="https://d30wms7jgjmff8.cloudfront.net/avatars/190/streama5e1bed52918ac859ed988618e7a2bad.jpg" width="65"></a> </div> <div class="mobile-meta show-for-small"> Suggested by <a href="/neighbors/abarad">Amy Barad</a><br> Jun 11, 2011 </div> </div> <div class="item-pointer"></div> <div class="item-content"> <div class="bubble-stream main-item"> <div class="has-media item-main"> <div class="stream-media"> <a href="/ideas/nola-the-ability-to-recycle-gl"><img alt="image" height="159" src="https://d30wms7jgjmff8.cloudfront.net/images/107/streamf97520b5053a463e8465195222e98a07.jpg" width="212"></a> </div> <div class="text"> <div class="text-body"> <a href="/ideas/nola-the-ability-to-recycle-gl">398 neighbors want the ability to recycle glass in New Orleans.</a> </div> <div class="sub"> <span class="actions"><a href="/ideas/nola-the-ability-to-recycle-gl#actions" class="btn white-border large"><strong>2</strong> actions</a></span><form action="/votes/803" class="button_to" method="post"> <div> <span class="actions"> <input name="_method" type="hidden" value="delete"> <input class="btn mint large" type="submit" value="Undo"> <input name="authenticity_token" type="hidden" value="vi66rEYBUkiqZVqss7DT/JhDbaN4GSdadEtk34ijRBg="> </span> </div></form> </div> </div> </div> <div class="rule-mint-xlt"></div> <div class="bubble-head new-supporters"> <span>New Supporters</span> <a href="/neighbors/brittwright" class="tiny-avatar-lnk"><img alt="Britt Wright" height="22" src="https://d30wms7jgjmff8.cloudfront.net/assets/avatar_medium_8.png" width="22"></a> <a href="/neighbors/rosemary" class="tiny-avatar-lnk"><img alt="Rosemary" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/25636/thumb0d559f628e6e05c8f32a179ba44e80a6." width="22"></a> <a href="/neighbors/willmarshall" class="tiny-avatar-lnk"><img alt="Will M." height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/26049/thumb2ae0e8a2760bcec545ae2655c497e2b1." width="22"></a> <a href="/neighbors/alex5" class="tiny-avatar-lnk"><img alt="Alex" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/26707/thumb511139a75432ee1b6dc9ad6f90b06ca2.jpg" width="22"></a> <a href="/neighbors/mike3" class="tiny-avatar-lnk"><img alt="Mike " height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/24145/thumbc9a0b03a4f25bcbb9f37de0486e4df10.png" width="22"></a> <a href="/neighbors/jaba4017" class="tiny-avatar-lnk"><img alt="Bill Arceneaux" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/3891/thumb6d95461aad25696fc0b4d69a4685f2f8.jpg" width="22"></a> <a href="/neighbors/faubourgstjohn" class="tiny-avatar-lnk"><img alt="Charlie London" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/203/thumb9872b2f76cdbcd64893f8855f73129cb.jpg" width="22"></a> <a href="/neighbors/andrewjameson" class="tiny-avatar-lnk"><img alt="Andrew Jameson" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/25316/thumb17689e5da8b64a01fc585438679037d4.jpg" width="22"></a> <a href="/neighbors/jenaoh1" class="tiny-avatar-lnk"><img alt="Jena Oh" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/25255/thumb1da559a045c471284e83cfded82f6e82." width="22"></a> <a href="/neighbors/rosemeistr" class="tiny-avatar-lnk"><img alt="rosemeistr" height="22" src="https://d30wms7jgjmff8.cloudfront.net/assets/avatar_medium_1.png" width="22"></a> </div> <div class="bubble-unit top-shadow hide-for-small bottom"> <span class="city-flag"><a href="/cities/nola">New Orleans</a></span> Suggested by <a href="/neighbors/abarad">Amy Barad</a> on Jun 11, 2011 </div> <div class="progress-flag"></div> </div> </div>

me_too_link

HTML����������� ������������������  on����������� ������������������  page

<div class="stream-item"> <div class="item-rail"> <div class="avatar-stream"> <a href="/neighbors/abarad" class="avatar-lnk" data-username="abarad"><img alt="Amy Barad" height="65" src="https://d30wms7jgjmff8.cloudfront.net/avatars/190/streama5e1bed52918ac859ed988618e7a2bad.jpg" width="65"></a> </div> <div class="mobile-meta show-for-small"> Suggested by <a href="/neighbors/abarad">Amy Barad</a><br> Jun 11, 2011 </div> </div> <div class="item-pointer"></div> <div class="item-content"> <div class="bubble-stream main-item"> <div class="has-media item-main"> <div class="stream-media"> <a href="/ideas/nola-the-ability-to-recycle-gl"><img alt="image" height="159" src="https://d30wms7jgjmff8.cloudfront.net/images/107/streamf97520b5053a463e8465195222e98a07.jpg" width="212"></a> </div> <div class="text"> <div class="text-body"> <a href="/ideas/nola-the-ability-to-recycle-gl">398 neighbors want the ability to recycle glass in New Orleans.</a> </div> <div class="sub"> <span class="actions"><a href="/ideas/nola-the-ability-to-recycle-gl#actions" class="btn white-border large"><strong>2</strong> actions</a></span>

<cr me_too_link> </div> </div> </div> <div class="rule-mint-xlt"></div> <div class="bubble-head new-supporters"> <span>New Supporters</span> <a href="/neighbors/brittwright" class="tiny-avatar-lnk"><img alt="Britt Wright" height="22" src="https://d30wms7jgjmff8.cloudfront.net/assets/avatar_medium_8.png" width="22"></a> <a href="/neighbors/rosemary" class="tiny-avatar-lnk"><img alt="Rosemary" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/25636/thumb0d559f628e6e05c8f32a179ba44e80a6." width="22"></a> <a href="/neighbors/willmarshall" class="tiny-avatar-lnk"><img alt="Will M." height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/26049/thumb2ae0e8a2760bcec545ae2655c497e2b1." width="22"></a> <a href="/neighbors/alex5" class="tiny-avatar-lnk"><img alt="Alex" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/26707/thumb511139a75432ee1b6dc9ad6f90b06ca2.jpg" width="22"></a> <a href="/neighbors/mike3" class="tiny-avatar-lnk"><img alt="Mike " height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/24145/thumbc9a0b03a4f25bcbb9f37de0486e4df10.png" width="22"></a> <a href="/neighbors/jaba4017" class="tiny-avatar-lnk"><img alt="Bill Arceneaux" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/3891/thumb6d95461aad25696fc0b4d69a4685f2f8.jpg" width="22"></a> <a href="/neighbors/faubourgstjohn" class="tiny-avatar-lnk"><img alt="Charlie London" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/203/thumb9872b2f76cdbcd64893f8855f73129cb.jpg" width="22"></a> <a href="/neighbors/andrewjameson" class="tiny-avatar-lnk"><img alt="Andrew Jameson" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/25316/thumb17689e5da8b64a01fc585438679037d4.jpg" width="22"></a> <a href="/neighbors/jenaoh1" class="tiny-avatar-lnk"><img alt="Jena Oh" height="22" src="https://d30wms7jgjmff8.cloudfront.net/avatars/25255/thumb1da559a045c471284e83cfded82f6e82." width="22"></a> <a href="/neighbors/rosemeistr" class="tiny-avatar-lnk"><img alt="rosemeistr" height="22" src="https://d30wms7jgjmff8.cloudfront.net/assets/avatar_medium_1.png" width="22"></a> </div> <div class="bubble-unit top-shadow hide-for-small bottom"> <span class="city-flag"><a href="/cities/nola">New Orleans</a></span> Suggested by <a href="/neighbors/abarad">Amy Barad</a> on Jun 11, 2011 </div> <div class="progress-flag"></div> </div> </div></div>

me_too_link

HTML����������� ������������������  in����������� ������������������  memcache

def replace_from_hash(hash) hash.each do |key, value| gsub! cache_replace_key(key), value.to_s endend

cache_rocketreplace_key = ‘<cr me_too_link>’html = ‘<form><div>etc...</div></form>’fragment.gsub! replace_key, html

gsub!

render_cached 'top', replace: 'inner'

a����������� ������������������  partial

= render ‘inner’= cache_replace_key :inner

top.html.haml

render_cached 'top', replace: ['inner', ‘footer’]

partials

#here = cache_replace_key :inner#there = cache_replace_key :footer

top.html.haml

render_cached 'top', replace: {key: a_helper(x)}

value

= cache_replace_key :keytop.html.haml

render_cached 'item',collection: objects,replace: {key: ->(o){a_helper(o)}}

Proc����������� ������������������  for����������� ������������������  each����������� ������������������  item

= cache_replace_key :keyitem.html.haml

def replace_item_hash(item, replace_hash) item_fragment = self.value.dup

replace_hash.each do |key, proc| item_fragment.gsub! cache_replace_key(key), proc.call(item) end

item_fragmentend

gsub!

extra����������� ������������������  string����������� ������������������  replacementdifferent����������� ������������������  render����������� ������������������  syntaxadds����������� ������������������  a����������� ������������������  dependency

cost

cache����������� ������������������  more����������� ������������������  stuff>����������� ������������������  more����������� ������������������  hits>����������� ������������������  faster����������� ������������������  pages

less����������� ������������������  stuff����������� ������������������  in����������� ������������������  cache>����������� ������������������  more����������� ������������������  hits>����������� ������������������  less����������� ������������������  RAM

benefit

No Caching 123 msRussian Doll* 67 msCacheRocket 113 msCacheRocket collection 82 ms

speed

efficiency Hits MissesRussian Doll 1400 100CacheRocket 14 1

efficiency Items SizeRussian Doll 100 120.9kCacheRocket 1 0.9k

Cat