I recently had a need to enable adding prefetching, preloading and prerendering markup to a Rails engine in such a way that the applications that consume the engine don't necessarily need to provide any content to the engine. This way the applications can upgrade to the latest version of the engine without breaking or having to add preloading code to every single controller. In keeping with the idea that functionality should be modularized as much as possible, I separated the logic into a gem.
Rails Preloadables exposes a view helper that takes a simple hash of domains, assets, and pages that you would like to render prefetching markup for and outputs the appropriate markup.
In addition to being capables of being inserted into a template without completely borking your application, using the preloadables_meta
method also allows you to dynamically adjust the markup in your controller based on the particular route requested. So, for example, in a series of posts where a visitor is very likely to click on the "next post" button, you might want to just prerender the next page every time:
# in app/controllers/posts_controller.rb
def show
@current_post = Posts.find_by_url(request.request_uri)
@preloadables = {
pages: [
Posts.get_next_post_after(@current_post)
]
}
render 'post'
end
This way Preloadables would render markup on each page instructing browsers to download and prerender the next page for each page in the background. Clicking the "next post" button would seem to have instant results to the user. Pretty nifty!
This is my first ever rubygem so be kind and give it a star on GitHub :-)