[Feature Proposal][PR Attached] Fragment Caching support for Renderabes

Hello Rails core :wave: I’m trying to explore options for getting Fragment Caching to work with Renderables. I’ll start at the beginning…

WTF is a Renderable?

A ViewComponent class is a prime example on the fully-featured end of the scale, but a “Renderable” can also be a humble PORO which encapsulates some custom rendering logic and implements #render_in or #to_partial_path, as per this example.

Ultimately their usage looks a bit like this:

<%= render MessageRenderable.new("Hello world!") %>

Renderables in Rails

Currently, ActionView has various bits of explicit support for using Renderables in the view layer, for example here in ActionView::Renderer or in ActionView::Template::Renderable.

I’m interested in bringing support for Renderables into the parts of ActionView responsible for Fragment Caching, as there is currently no compatibility at all, meaning Fragment Caching is unusable.

I’m trying to approach this in a way that treats Renderables as a relatively generic duck-type that isn’t tied to any specific implementation, so that ActionView itself doesn’t need to know the details of what or how any given Renderable class is doing under the hood.

Adding Fragment Caching Support

The missing piece of the puzzle revolves around the creation of digests and mapping of dependencies in ActionView::Digestor and ActionView::DependencyTracker respectively. Renderables are currently ignored, which means that any changes in related files are not reflected in the digests used to create composite cache keys used for fragments, so the cache entries are not invalidated when they should be (when the files’ contents change).

Adding this support requires some minor changes so that;

  • when render dependencies are being enumerated by ActionView::DependencyTracker it recognises render calls involving Renderables
  • when ActionView::Digestor receives a list of dependencies that includes Renderables, it handles them slightly differently to regular partials

I’ve made an initial PR here: Fragment Caching for Renderables by Matt-Yorkley · Pull Request #42850 · rails/rails · GitHub

1 Like