Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails from "good" to fast - Colognerb

Rails from "good" to fast - Colognerb

Rails from "good" to fast. How to get the view rendering from ~600ms to ~60ms.
https://github.com/timoschilling/YetAnotherBlog
https://github.com/apotonick/cells
https://github.com/apotonick/representable

0d538506cb7d350250906243645c28d4?s=128

Timo Schilling

February 17, 2016
Tweet

Transcript

  1. Rails from “good” to fast How to get the view

    rendering from ~600ms to ~60ms
  2. What’s the slowest part in Rails? • Request Handling (ActionDispatch)

    • NO! • Database Queries (ActiveRecord) • NO, just a bit! • Rendering (ActionView, HAML, JBuilder) • YES!
  3. Let’s build a Blog github.com/timoschilling/YetAnotherBlog Why ~5ms?

  4. Asset Overhead Prod Dev 1 Asset Dev 100 Assets

  5. Fix Asset Overhead How? Dev 1 Asset Dev 100 Assets

  6. Even Faster?

  7. The Code

  8. Render a Index with 100 Items

  9. Side Note:
 Every Query is a lie! 0.3ms + 0.4ms

    + 4.4ms +0.6ms = 5.7ms 5.7ms != 6.1ms
  10. None
  11. Why 5.7ms != 6.1ms? ActiveRecord show only the query time!

    Not the real amount of each operation!
  12. How to get a real value? Before: (0.3ms) SELECT COUNT(*)…


    Post Load (0.4ms) …
 User Load (0.4ms) …
 Comment Load (4.4ms) …
 User Load (0.6ms) … 
 
 Completed in 568ms
 (Views: 561.9ms |
 ActiveRecord: 6.1ms) After: (0.3ms) SELECT COUNT(*)…
 Post Load (0.4ms) …
 User Load (0.4ms) …
 Comment Load (4.4ms) …
 User Load (0.6ms) …
 
 DB Queries: 78.85ms
 
 Completed in 568ms
 (Views: 489,1ms |
 ActiveRecord: 6.1ms)
  13. Hint! If you use Trailblazer:
 You will get this kind

    of measurement for free, in the future.
  14. How to make it faster? Cache!?

  15. Russian Doll Caching from 570ms to 677ms ???

  16. Russian Doll Caching It helps only if you have slow

    views! This view has the same render time as a view without `sleep` with Russian Doll Caching
  17. good old Rails.cache.fetch It’s fast!
 But now I need to

    manage the cache!
 :( 85ms
  18. tl;dr Rails caching sucks!

  19. Again: How to make it faster? Don’t use ActionView! But

    how? Use Cells!
  20. Cells? A gem for ViewModel’s,
 written by this awesome guy:

  21. Demo

  22. Status:
 ~650ms -> ~150ms

  23. Where is the Time? • 150ms Request • DB: 70ms

    • ActiveRecord: 6.1ms • ActionView: 78.1ms • Cells: 71.4ms
  24. Next Step: remove index (action)view (demo)

  25. Where is the Time? • 145ms Request • DB: 70ms

    • ActiveRecord: 6.1ms • ActionView: 74.1ms • Cells: 71.4ms
  26. Next Step: remove layout (action)view (demo)

  27. Where is the Time? • 145ms Request • DB: 70ms

    • ActiveRecord: 6.1ms • Cells: 71.4ms
  28. How does tempting works?

  29. Why need that ~70ms? • 1 Layout • Index List

    • 100 Post • + 1 User • + 1 Comment • + 1 User • = 404 Renderings • 404 Renderings • each rendering needs 100 method call (theoretical assumption)
  30. 70ms vs. 4ms Where the time goes by? Tilt!

  31. What does Tilt do? • one time • compile the

    template • build a method • cache this method • per rendering • bind the method to the context • call the method • unbind the method from context • one time • compile the template • build a method • cache this method • per rendering • bind the method to the context • call the method • unbind the method from context
  32. Solution: Hand build tilt replacement

  33. Where is the Time? • 91ms Request • DB: 70ms

    • ActiveRecord: 6.1ms • Cells: 17.4ms
  34. ActiveSupport::Notifications • Nice • But slow • One event costs

    ~0.05ms
  35. Path helpers • post_path(model) # => f***ing slow • post_path(id:

    model.id) # => slow • “/posts/#{id}” # => fast • brings up to 4ms (50%)
  36. Cell::Mailer

  37. Real World App

  38. Jbuilder

  39. Faster? How? A gem JSON/XML Object Mapper,
 written by this

    awesome guy: Representable
  40. Representable

  41. Jbuilder
 vs.
 Representable from ~230ms to ~80ms

  42. Form’s SimpleForm

  43. Faster? How? A form builder gem,
 written by this awesome

    guy: Formular
  44. Formular SimpleForm 11ms vs. Formular 0.6ms

  45. Disclamer I’m an apotonick fanboy!

  46. The End

  47. Tanks!

  48. Questions?

  49. Links • github.com/timoschilling/YetAnotherBlog • github.com/apotonick/cells • github.com/apotonick/representable