Speed up rendering Rails pages with this gem.
render_async
renders partials to your views asynchronously. This is done
through adding Javascript code that does AJAX request to your controller which
then renders your partial into a Rails view.
Workflow:
- user visits a Rails page
- AJAX request on the controller action
- controller renders a partial
- partials renders in the place where you put
render_async
helper
Javascript is injected into <%= content_for :render_async %>
so you choose
where to put it.
Add this line to your application's Gemfile:
gem 'render_async'
And then execute:
$ bundle install
-
Include
render_async
view helper somewhere in your views:# app/views/comments/show.html.erb <%= render_async comment_stats_path %>
-
Then create a route that will
config/routes.rb
# config/routes.rb get :comment_stats, :controller => :comments
-
Fill in the logic in your controller
# app/controllers/comments_controller.rb def comment_stats @stats = Comment.get_stats render :partial => "comment_stats" end
-
Create a partial that will render
# app/views/comments/_comment_stats.html.erb <div class="col-md-6"> <%= @stats %> </div>
-
Add
content_for
in your base view file# application.html.erb <%= content_for :render_async %>
render_async
takes two arguments, path
and html_options
.
path
is the AJAX-capable controller action you're looking to call viaGET
. e.g.comments_stats_path
,posts_path
, etc.html_options
is an optional hash that gets passed to a railsjavascript_tag
, to drop html tags into thescript
element.
Example of utilizing html_options
with a nonce
:
<%= render_async users_path, nonce: 'lWaaV6eYicpt+oyOfcShYINsz0b70iR+Q1mohZqNaag=' %>
Rendered code in the view:
<div id="render_async_18b8a6cd161499117471">
</div>
<script nonce="lWaaV6eYicpt+oyOfcShYINsz0b70iR+Q1mohZqNaag=">
//<![CDATA[
(function($){
$.ajax({ url: "/users" }).always(function(response) {
$("#render_async_18b8a6cd161499117471").replaceWith(response);
});
}(jQuery));
//]]>
</script>
render_async
can be called with a block that will act as a placeholder before
your AJAX call finishes.
Example of passing in a block:
<%= render_async users_path do %>
<h1>Users are loading...</h1>
<% end %>
Rendered code in the view:
<div id="render_async_14d7ac165d1505993721">
<h1>Users are loading...</h1>
</div>
<script>
//<![CDATA[
(function($){
$.ajax({ url: "/users" }).always(function(response) {
$("#render_async_14d7ac165d1505993721").replaceWith(response);
});
}(jQuery));
//]]>
</script>
After AJAX is finished, placeholder will be replaced with the request's response.
render_async
can utilize view fragment caching to avoid extra AJAX calls.
In your views:
# app/views/comments/show.html.erb
# note 'render_async_cache' instead of standard 'render_async'
<%= render_async_cache comment_stats_path %>
# app/views/comments/_comment_stats.html.erb
<% cache render_async_cache_key(request.path), :skip_digest => true do %>
<div class="col-md-6">
<%= @stats %>
</div>
<% end %>
- The first time the page renders, it will make the AJAX call.
- Any other times (until the cache expires), it will render from cache instantly, without making the AJAX call.
- You can expire cache simply by passing
:expires_in
in your view where you cache the partial
After checking out the repo, run bin/setup
to install dependencies. Then, run
rake spec
to run the tests. You can also run bin/console
for an interactive
prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To
release a new version, update the version number in version.rb
, and then run
bundle exec rake release
, which will create a git tag for the version, push
git commits and tags, and push the .gem
file to
rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/renderedtext/render_async.
The gem is available as open source under the terms of the MIT License.
Thanks goes to these wonderful people (emoji key):
Nikola Đuza 💬 🐛 💻 📖 💡 👀 |
Colin 💻 📖 |
Kasper Grubbe 💻 |
Sai Ram Kunala 📖 |
Josh Arnold 💻 📖 |
Elad Shahar 💻 |
---|
This project follows the all-contributors specification. Contributions of any kind welcome!