Saturday, May 18, 2024
HomeRuby On RailsRushing Up Rendering Rails Pages with render_async

Rushing Up Rendering Rails Pages with render_async




Speeding Up Rendering Rails Pages with render_async

Including new code to Rails controllers can carry a few issues with it. Generally controller actions get actually huge, they usually are likely to do a number of issues. One other frequent downside is a rise in knowledge over time, which may result in gradual web page loading time. Including new code to controller actions may generally block the rendering of some actions if it fails, breaking person expertise and person happiness.

Right here at Semaphore, we got here throughout these kinds of issues a few instances. We often resolved them by splitting controller actions into smaller actions, and rendering them asynchronously utilizing plain JavaScript.

After a while, we noticed that this may be extracted to render_async, a gem that hastens Rails pages for you – it hundreds content material to your HTML asynchronously by making an AJAX name to your Rails server.

Downside no. 1: Slowness accumulates over time

As new code will get added, Rails controller actions can get “fats”. If we’re not cautious, web page load time slowly will increase as the quantity of code and knowledge rises.

Downside no. 2: Coping with code that blocks your actions

As we add new code to our controllers, we generally have to load additional knowledge within the controller motion as a way to render the whole view.

Let’s check out an instance of code that blocks the rendering of an motion.

Let’s say we’ve a movies_controller.rb, and within the present motion we wish to fetch a film from the database, however we additionally wish to get the film ranking from IMDB.

class MoviesController < ApplicationController
  def present
    @film = Films.find_by_id(params[:id])

    @movie_rating = IMDB.movie_rating(@film)
  finish
finish

Getting the film by find_by_id is a standard line that tries to discover a film in our database that we can management.

Nonetheless, the road the place we fetch the film ranking makes an exterior request to an IMDB service that’s anticipated to return the reply. The issue begins when an exterior service isn’t out there or is experiencing downtime. Now our MoviesController#present is down and can’t be loaded to the person that desires the film.

The answer

Each issues will be solved or relieved by splitting your code utilizing the rendered_async gem. rendered_async hundreds content material asynchronously to your Rails pages after they’ve rendered.

Why select rendered_async over conventional JavaScript code that does async requests and provides HTML to the web page? As a result of rendered_async does the boring JavaScript fetch and change for you.

How render_async works

Let’s say you’ve an app/views/motion pictures/present.html.erb file that reveals particulars a couple of specified film and rankings it fetches from an exterior service.

Right here’s the code earlier than utilizing render_async:

# app/views/motion pictures/present.html.erb

Details about <%= @film.title %>
<%= @film.description %>

<%= render_async movie_rating_path(@film.id) %>

And that is what it appears like after utilizing render_async:

# app/views/motion pictures/present.html.erb

Details about <%= @film.title %>
<%= @film.description %>

<%= render_async movie_rating_path(@film.id) %>

With rendered_async, the part with the film ranking is loaded after the present.html.erb hundreds. The web page makes an AJAX request utilizing jQuery to movie_rating_path, and it renders the contents of the AJAX response within the HTML of the web page.

Since rendered_async makes a request to the desired path, we have to add it to config/routes.rb:



get :movie_rating, :controller => :motion pictures

We additionally want so as to add a correct motion within the controller we set within the routes, so we’ll add the movie_rating motion inside movies_controller.rb:



def movie_rating
  @movie_rating = IMDB.movie_ratings(@film)
  render :partial => "movie_ratings"
finish

Since our movie_rating is rendering a partial, we have to create a partial for it to render:

# app/views/motion pictures/_movie_rating.html.erb
Film ranking on IMDB: <%%= @movie_rating %>

Crucial half is so as to add the content_for tag to your software structure, as a result of rendered_async will put the code for fetching AJAX responses there. It’s greatest is to place it simply earlier than the footer in your structure.

# app/views/layouts/software.html.erb
<%= content_for :render_async %>

If the IMDB service is down or not responding, our present web page will load with out the film ranking. The film web page now can’t be damaged by an exterior service, leaving the remainder of the web page absolutely usable.

Wrapping Up

On this instance we managed to hurry up rendering Rails pages with rendered_async by:

  1. Simplifying the MoviesController present motion, thus making it simpler to check and cargo.
  2. Splitting our film ranking markup right into a partial, which is an efficient sample within the Rails world, and
  3. Releasing up present motion from being blocked by an exterior service.

When you have concepts on what else could possibly be added or improved in render_async, you’ll be able to submit a pull request or a problem at render_async.

Additionally, be happy to depart any feedback or questions you could have on
Twitter or
ship me an electronic mail. For those who discover this text
helpful, or assume another person would discover it helpful, please share it with the
world.



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments