Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

An MVC HTML Helper to Asynchronously Load Partial Views

0.00/5 (No votes)
18 Sep 2017 2  
Speed up the loading of the main view by automatically loading partial views in async

Introduction

Sometimes, an index page may take too long to load, usually because the needed data comes from long running process or slow resources (slow DB, lazy web services, particular data calculation, etc.).

Of course, the first thing to do is to try to clear these problems by means of DB optimization, code review, data paging and so on. But as a last chance, to improve the experience of a user waiting in front of a browser, what we can do is to provide him something as soon as we have it, and to complete page later, as soon as data are available.

Partial Views and HtmlHelper Extension Methods

Everybody knows and uses partial views in MVC and how they are included in a main View, typically an index page.

This extension is a new HtmlHelper doing the dirty job of displaying a 'preview' partial view, calling the real one behind the scenes and finally showing the complete version as soon as ready, possibly calling it with one line of code.

Using the Code

@Html.AsyncPartial("MyController","MyAction")

This is the simplest usage of the extension that, in place of Html.Partial, will provide to:

  • load directly in the parent view a partial named in this case "MyAction_Preview", that typically is a Model-less partial view. It should appear similar to the final view, but just presenting a waiting spinner or what you prefer.
  • wrap the HTML of the preview partial into a container, and inject, as inline code or wherever we decide, the JavaScript code that will call MyController/Myaction
  • replace the container content with the async response got by JavaScript

The result is the preview Partial view ...

...replaced by the complete Partial view once data is available.

The complete extension signature is as follows:

public static MvcHtmlString AsyncPartial(this HtmlHelper helper,
     string controller,
     string action,
     string previewPartialName=null,
     AjaxMethods method = AjaxMethods.GET,
     TempDataDictionary TempData=null)

previewPartialName: if provided, it will be the name of the 'preview' partial view displayed while waiting for the async call to be completed. Defaults to "{action}_preview"

method: POST or GET to be used to call the Action in the controller. Defaults to GET.

TempData: If provided, the Dictionary will contain the JS script to be added to the page calling the partial view. If not, the script will be included as inline code right after the partial view HTML as to be executed during the rendering of the HTML page.

In the main View, this is what you need:

@using Helper.Extensions
......

@Html.AsyncPartial("home", "getdata")

The @using directive imports the namespace used in the helper class (downloadable).

Of course, in this case, you would need a home controller containing a getdata Action.

public ActionResult GetData()
{
   PopulationModel model = new PopulationModel();
   return View(model);
}

Views getdata.cshtml and getdata_preview.cshtml should exist. The first one in this case needs a model, the second doesn't.

Script Position

If you choose to pass TempData dictionary to the helper, the JS script will be added to the main view where you type:

<script>@Html.Raw(TempData["script"])</script>

By default, JS script is injected as inline code after partial view HTML.

Click to Refresh

The white refresh-icon on the top right of the partial view will actually refresh the content sending an Ajax request. If you need, just include in your view an anchor tag having a data-partial-refresh attribute. An onclick event will be added by the helper, calling the needed JS function.

<a data-partial-refresh href="#">
<span class="glyphicon glyphicon-refresh"></span></a>

Author

Max Aronica is a senior .NET full-stack Developer working as external consultant for enterprise customers in Rome, Italy.

History

  • 18/09/2017 : attached missing Demo solution

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here