A Lazy Javascript, a Ruby Load and a Sponge plugin to a bar

Lazy Load Content

Sometimes a portion of your page takes a really long time to generate and render. Instead of allowing the user to spin his thumbs, you can display the bulk of content to user and send off a separate ajax request to gather the “slow” data. Lazy Load Content makes late loading a portion of your page through ajax as easy as setting up a remote_function call. With options to render fragment cached if they exist, and perform the late load if not, your app will fly like the sloth eating eagle.


ruby script/plugin install  http://arperftoolkit.rubyforge.org/svn/trunk/lazy_load_content/

Copy the file javascripts/lazyLoadContent.js into your public/javascripts folder and include it with prototype.js in your views.

The Basics:

In your rhtml or haml file:

<h1> I love giraffes.. basically </h1>
<% lazy_load(:remote => {:update => 'lazyLoadContent', :url => {:action => 'lazy_load_action'}})do -%>
  <div id = "lazyLoadContent"> We wait while the giraffes are smelling themselves. </div>
<% end -%>

In your controller define the specified function

def lazy_load_action
  render :text => 'The giraffes are ready!'

When the page loads, the loading text is displayed: We wait while the giraffes are smelling themselves.
Then after the ajax call we see: The giraffes are ready!

…….. and more……….

Fragment cache integration

Specify the fragment cache parameters in :cache. If the fragment cache exists, the content is inserted
into the file and an ajax call is not performed. If the fragment does not exist, the loading content appears and the ajax call is performed to retrieve the data:

haml file lazy_load_test.haml:

- lazy_load(:remote => {:update => 'lazyLoadContent', :url => {:action => 'lazy_load_cache_action'}}, | :cache => {:id => params[:id],  :action => 'cached_action'}) ) do |
   #lazyLoadContent While we are waiting for the giraffes to smell each other....

in your controller lazy_load_controller.rb:

def lazy_load_cache_action
  render :partial => 'cached_action'

in the partial _cached_action.haml:
Note that the cache parameters here are exactly the same as the parameters given to cache in the lazy_load function

- cache(:id => params[:id], :action => 'cached_action')
    love cache!

This is compatible with the timed_fragment_cache plugin, by specifying a second parameter with the expiry in both the cache call AND the lazy_load call.

:cache => {:id => params[:id], :action => 'cached_action', :expiry => 15.minutes.from_now}

Combining multiple requests

By using the :bulk option instead of the :remote option, you can combine multiple lazy load calls with the same url into one ajax call. This is convenient if you need to load multiple data during one call and wish to avoid multiple round trips. This option is only available when :dom_type => :dom_element as discussed below. Unique parameters for each lazy load can be specified in the :params option as shown below.

In the controller, individual parameters will be available as an array of hash maps in params[:lazy_load].

Parameters: {"action"=>"lazy_load_bulk_action", "controller"=>"lazy_load_test",  "lazy_load"=>[{"id"=>"1", "update"=>"lazyLoadContentOne"}, {"id"=>"2", "update"=>"lazyLoadContentTwo"}]}

Would be produced from the following:

- lazy_load(:dom_type => :dom_element, |
 :bulk => {:update => 'lazyLoadContentOne', |
 :params => {:id => 1}, |
 :url => {:action => 'lazy_load_bulk_action'}}) do |
       Loading ONE... - lazy_load(:dom_type => :dom_element, |
 :bulk => {:update => 'lazyLoadContentTwo', |
 :params => {:id => 2}, |
 :url => {:action => 'lazy_load_bulk_action'}}) do |
       Loading TWO...

Types of lazy load

  1. javascript: (default) inline javascript that responds the the document onLoad event
  2. dom_element: insert hidden divs with request information
  3. store: Stores all options for later use by integrator


inline javascript responds to the document onLoad event to submit the Ajax request

document.observe("dom:loaded", function() {new Ajax.Updater('lazyLoadContent', '/lazy_load_test/lazy_load_action', {asynchronous:true, evalScripts:true})});


Insert hidden divs into the DOM with class=”lazyLoadContent” and information for the ajax request. The javascript executed at the end then searches for classes on initialization and executes the ajax request based on their content. This is the preferred method used by Spongecell as it allows us to execute static javascript, and defers most of the javascript execution at the end of the page. Sponge Tom and Sponge Andrey gave me some sweet suggestions with this technique and the javascript development and by moving most of the javascript to the bottom of the page our app ate sloths like a super falcon.

This technique requires inclusion of lazyLoadContent.js in the document. Please copy the file into your public/javascripts and include it with prototype.js in your view

= javascript_include_tag "vendor/prototype"

= javascript_include_tag "vendor/lazyLoadContent/lazyLoadContent"
<div class="lazyLoadContent" lazyloadeval="new Ajax.Updater('lazyLoadContent', '/lazy_load_test/lazy_load_action', {asynchronous:true, evalScripts:true})" style="display:none"></div>

Tags generated using the :bulk option are slightly different.

<div class="lazyLoadContent" params="{"update": "lazyLoadContentOne", "id": 1}" style="display:none" url="/lazy_load_test/lazy_load_bulk_action"></div>


This method renders nothing, but stores the options for later retrieval.

Bottom Line

Use this easy trick make your app snappy and fun. This is version 0.00001 so yer complaints suggestions and comments.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: