Lazy loading of search results

This post shows how you may implement lazy loading for search results (or any other viewer) web part.

Last time lazy loading became "must to have" feature in the world of web, especially when talking about mobile devices experience. We apply lazy loading for loading images or more data on demand.

Last days I've been working on the mobile site built with Kentico CMS and main purpose of that application was search through thousands of  record. Of course Kentico smart search capabilities were utilized to reach a goal. Smart search results web part was used to show the result on the page. Everyone who worked with that web part knows that it shows default pager control when there were more results found than page size. 

The issue I run into with that pager are:
The look of the control makes me feel like I'm back in time for 10 years - the nice thing here is that Kentico allows us to adjust the layout, styling, add or remove controls
Pager allows me to switch between pages, but what I need, in my particular case, is increasing page size until there are more available search results
My personal preference when working with Kentico CMS is to avoid customization as much as possible. So I've started to look for the solutions within Kentico features.

So, as you've might already guess, we are going to work with pager settings of the Smart search results web part. First thing I did in order to achieve my goal was:

  • setup pager page size to any reasonable value, let's say 25
  • setup paging mode to PostBack
  • check hide pager for single page
Next things we need to take care of are pager transformations. In this particular case we need just two transformations:
  • Pager layout
    • It should contain just one place holder for next page transformation. Why next? - Simply because Kentico will hide it when there is no more pager (more available search results). So my trasformation looks the following way:
<asp:PlaceHolder runat="server" ID="plcNextPage"></asp:PlaceHolder>

  • Next page
    • This transformation should increase smart search results page size instead of taking user to the next page. That's why the look of my transformation is:
<div id="loadMore"> </div>
<div style="margin: 10px;">
  <asp:Button class="btn btn-default btn-block" runat="server" text="loading more items..." ID="btnMore" ClientIDMode="Static" />
<script runat="server">
  protected override void OnLoad(EventArgs e)
      Control parent = this;      
      while ( (!(parent is CMS.Controls.UniPager)) && 
             (parent != null))
        parent = parent.Parent;
      if (parent != null && parent is CMS.Controls.UniPager)
        (parent as CMS.Controls.UniPager).PageSize = (parent as CMS.Controls.UniPager).PageSize + 25;        

This transformation contains a button that user might click when reached the bottom of the page, so it will trigger postback and fire OnLoad method implemented in the transformation, which increases the size of the page (amount of items to show). Another approach (the one I've chose) is to implement javascript that will click the button instead of user when reaching the bottom of the page. I'm not going to publish my javascript code as it has not any relation with Kentico as well as it is just the matter of developer preferences which one to use.

The final step is checking Use update panel setting of the Smart search results web part. After doing this your page should smoothly load more and more results.

This approach could be also used with other viewers, like repeater, but in this case I'd like to admit that described implementation is not a real lazy loading, but its mimicking, so it is strogly recommended to use AJAX + Kentico Rest service for data lazy loading in any other cases. You might ask me why have I used this approach. The answer is: because there is no way to get search results with Kentico Rest service. Also I'd not recommend using it with large amount of data.

Here you can find an example of repeater with "lazy loading". As I've already mentioned, it is not recommended to use this approach with repeater. I used it just for demo purpose. Try to scroll down to the bottom of the page and see how approach works.

Please leave your thoughts and comments, you have on this approach, as well as approach you're using to resolve similar problems.

Thank in advance,
Roman Hutnyk