Friday, September 17, 2010

Loading a SharePoint Web Part asynchronously

Scenario:
How to load a SharePoint Web Part asynchronously?

Explanation:
Web Parts that require long loading time might significantly slow down the overall page performance by increasing the page load time.

This is especially true with SharePoint search web parts, web parts that interact with third party web services, web parts that deal with large SharePoint lists, etc…

I have created "Asynchronous Web Part Framework" that enables web parts to load asynchronously.

To load pages asynchronously element by element facebook-style to speed up the first display of the page the first choice would probably not be UpdatePanel as it is meant for partial page updates as opposed to partial page loads. Web parts using Asynchronous Web Part Framework can in fact leverage the UpdatePanel for partial page updates as well.

Web Parts that utilize the Asynchronous Web Part Framework support all the features of SharePoint web parts such as editor web part, web part connections etc…

The Asynchronous Web Part Framework can be applied to existing web parts with very few code changes.
The same framework can also be used for developing web parts for use in Asp.Net applications. (With few file and path changes to replace the SharePoint layouts folder, etc...)

As soon as the page is loaded, the web part loads and displays a spinner icon.




Then the web part properties, web part connection information are sent to the web part web service asynchronously and the HTML mark is them loaded into the web part asynchronously.





What is required?

A web part that utilizes the Asynchronous Web Part framework should consist of the below components:
  •  A Web Part control class that serves as a wrapper for collecting properties, connections
  •  A Web Part UI control class that is responsible for rendering HTML for the web part

    • This control contains all the web part logic
  •  A Web Service that loads the web part UI control and renders its HTML back to the web part
  •  A JavaScript file that defines handlers for interaction between the web part and web service
How does it work?

  1. The web part control acts as a wrapper for collecting properties from either the web part properties pane or editor part and for connections with other web parts.
  2. When the web part loads first, the content container in the web part is loaded with a spinner and the JavaScript handler is registered with the page
  3. The JavaScript method then sends the web part properties and connection data to the web service
  4. The web service loads the web part UI control with the web part properties / connection details
  5. Web Part is then rendered as html
  6. If caching is required to be applied, the control HTML is stored in cache
  7. The result HTML is then loaded into the web part content container



This project contains working version of a basic web part that is loaded asynchronously.

This code also demonstrates how web part connections and editor part can be implemented with an asynchronous web part.

This code is created using Visual Studio 2010 and works with ASP.NET 3.0 or higher, MOSS 2007 and SharePoint 2010.

The AsyncWebPart.cs control which acts as the web part wrapper calls the JavaScript method "AsyncWebPartGetData" with all the web part parameters / connection data



The JavaScript method "AsyncWebPartGetData" calls the web service method "GetUIHtml" from web service "AsyncWebPartService" with all the parameters



The Web Service method "GetUIHtml" loads the "AsynWebPartUI" control which performs the actual core functionality of the web part.

This method renders the "AsyncWebPartUI" control as Html.



The AsyncWebPartUI control performs the actual core functionality of the web part.

18 comments:

  1. We have a few webparts which are taking a long time to load... For example .. Weather which is written in Content editor Webpart and Google Maps for traffic whcih we bought .. can we apply this to them.. Can you pls help us with some documentation to set it up.. My email is schoud7@uic.edu ... Sharad

    ReplyDelete
  2. Hello I like this concept as our landing page on SP2010 is taking a long time due to CEWP of Weather and one market webpart which has google map traffic.. can we embed these with your code.. we can pay u consulting fees for this.. pls contact me at schoud7@uic.edu or 312-355-4124

    ReplyDelete
  3. Hi Sharad,

    This framework works only with custom web parts.

    But in your case, as you are using CEWPs, you should be able to load them pretty easily after the page loads through js/jquery

    ReplyDelete
  4. Hi

    I am having a small issue.
    That usercontrol that I use, need to cooperate with Page object or Viewstate.
    Page is each time null.
    Can you tell me another solution how can I get reference to Page object?
    Thanks

    ReplyDelete
  5. Peter,

    You will have to create new properties from Viewstate/Page if possible (that is the reason why I am passing the current Url i.e. Page.Request.QueryString["startRow"] via a property to the web service) and pass them to the asmx web service. The page object will always be null because its a static object.

    ReplyDelete
  6. Is there a way I can add a timer to refresh the web part asynchronously every X seconds?

    ReplyDelete
  7. Yes. You can by calling the setTimeout function.

    I have not tested this but you can try the below:

    this.Page.ClientScript.RegisterStartupScript(typeof(Page),
    "startupScript" + this.ClientID,
    string.Format(setTimeout("AsyncWebPartGetData('{0}','{1}','{2}','{3}','{4}', '{5}');",
    (RowLimit != null) ? RowLimit.Replace("'", Constants.SingleQuoteReplacer) : "",
    (UsePaging != null) ? UsePaging : false,
    (CacheResultMinutes != null) ? CacheResultMinutes : 0,
    (Page.Request.QueryString["startRow"] != null) ? Page.Request.QueryString["startRow"].ToString() : "",
    String.Format("{0}_{1}_{2}", Constants.CacheKey_AsyncWebPart, CurrentUserId, this.ClientID),
    _contentContainer.ClientID),2000),
    true);

    ReplyDelete
  8. I see your solution does not contain any Visual Web Part (the UserControl particulary). So how can I apply this if I have created a Visual Web Part? Do I need to get rid of the user control and generate every control and HTML programatically?
    Maybe I'm missing something silly.
    Thanks

    ReplyDelete
  9. Unfortunately, visual web parts do not work well with this approach. All the controls need to be web controls.

    ReplyDelete
  10. Can you provide some document or set of procedure steps to implement this to existing webpart.

    ReplyDelete
  11. Kunjan.. Here is some documentation: http://asyncwebpartframewrk.codeplex.com/documentation

    ReplyDelete
  12. Hey Chaitu..this link contains the same data which you have displayed here.

    ReplyDelete
  13. If your existing web part is not a visual web part, it may be quite easy to wrap it in this framework. What is the version of SharePoint that you are using? (2007/2010?) What is your development experience? junior / mid-level / senior developer?

    ReplyDelete
  14. Hey Chaitu, my existing webpart is not a visual web part its a custom web part. I am using SharePoint 2010, and my development experiment is junior.

    ReplyDelete
  15. Same question as kunjan...how do you implement this?! I'm not a programmer, I'm a Sharepoint administrator. I have one web part that I do not have source-code access to, that I want to make load asynchronously.

    ReplyDelete
  16. Hi Matt,

    It is not possible to load a web part with out modifying its source using this approach..

    ReplyDelete
  17. Ok, so assuming I could get a hold of the source code...what do I do with it? I looked at the sample project you posted and there seems to be a lot in there. I'm assuming I wouldn't need all of it?

    ReplyDelete
  18. Hi Matt

    You need to have some level of programming knowledge to be able to wrap your web part into this framework.

    Just let me know if you need more help when you get your source code and we can work something out.

    ReplyDelete