Dev4Side Articles

Perfomances improvement on the content selection with the SharePoint 2010 Client Object Model

By using SharePoint 2010 Client Object Model, we have seen how easy it is to retrieve information in the SharePoint sites and use them in our client side applications.

We have also seen (in the introduction article) that these class libraries only recall the WCF named "client.svc"; this service deal with  converting  the received request, executing the query to the SharePoint content database and giving back the result to the client application.
Hence, as there is an HTTP request,  whenever you wish to receive information from our SharePoint sites, it is necessary to focus your attention on the answer load of our requests, as your application could become very slow when handling with a massive data set.

In order to diminish the load of answers by the SharePoint server, the Client Object Model gives us the opportunity to apply one or two solutions to our code,  so we can choose to request ONLY what we really need.
In the previous articles, we have seen that a normal information request to the SharePoint 2010 server, which is executed with the client-side object model, it is mainly composed of 3 phases:

  1. Creation of the side-client context
  2. Selection of the information I intend to manage from my application client
  3. Execution of my request to the server

We can better see these 3 operations in this scheme:

  1. start(ing) point: ClientContext class
  2. Before being able to read the content, you need to request it!
  3. All requests should then be executed on the server

In this way, all items properties that we add to our request (with the use of the ClientContext class Load method) will be present in the answer that SharePoint produce.  If we intend to use only some of these properties inside our application, why don't we ask only that to the server?
By doing so we should reduce the load of the answer we receive by SharePoint.
In order to be sure of what I am saying, we can try to turn on any program that intercepts  the web traffic on our development machine ( I use the popular Fiddler) and try to retrieve the load of answer generated by this code:

ClientContext context = new ClientContext("http://servername");
using (context)
{
    Web web = context.Web;
    context.Load(web);
    context.ExecuteQuery();

    Console.WriteLine("Site: {0}", web.Title);
}

Note: in this example code, we have requested the information of a particular SharePoint site, but at the end we have used only the Title property.

As you can see in the figure, this request produces a 1.25 kb answer.

COMPerformance1

 

By using the second overload of Load method and the Lambda Expression syntax,  we have the possibility to specify which property to value on each object we add to our request.

ClientContext context = new ClientContext("http://servername");
using (context)
{
    Web web = context.Web;
    context.Load(web, w => w.Title);
    context.ExecuteQuery();

    Console.WriteLine("Site: {0}", web.Title);
}

By doing so, our client application will produce exactly the same result as before, but performances will be improved to the half. In fact, as you can see in the figure, the answer generated by this second code list, weights around 0.77 kb (before it weighted 1.25 kb).

COMPerformance2

 

If you want to resume the values of more properties, it is sufficient to separate the single Lambda Expressions with a comma.

ClientContext context = new ClientContext(http://servername);
using (context)
{
    Web web = context.Web;
    context.Load(web, w => w.Title, w => w.Created);
    context.ExecuteQuery();

    Console.WriteLine("Site: {0}", web.Title);
    Console.WriteLine("Created on: {0}", web.Created);
}

If you want to retrieve an item collection (for example all the lists in a SharePoint site or a group of an item list), specifying your intention of enhancing only some of the properties of the items in the requested collection ( in our example, the list title or the value  of a single item field), it is sufficient to use at least two different Lambda Expressions: the first one is useful to recall the "Inculde" generic method, which allows us to add some settings about the current item collection and the second one in order to specify the property to add to our request.

How to query only the item title and the item number of a list collection

ClientContext context = new ClientContext("http://servername");
using (context)
{
    ListCollection lists = context.Web.Lists;
    context.Load(lists, ls => ls.Include(l => l.Title, l => l.ItemCount));
    context.ExecuteQuery();

    foreach (List l in lists)
    {
        Console.WriteLine("{0} ({1})", l.Title, l.ItemCount);
    }
}

How to query only the value of specific fields in an item list

ClientContext context = new ClientContext("http://servername");
using (context)
{
    List list = context.Web.Lists.GetByTitle("Web Part Gallery");
    ListItemCollection items = list.GetItems(CamlQuery.CreateAllItemsQuery());
    context.Load(items, its => its.Include(i => i["FileLeafRef"], i => i["Title"]));
    context.ExecuteQuery();

    foreach (ListItem item in items)
    {
        Console.WriteLine("{0} - {1}", item["FileLeafRef"], item["Title"]);
    }
}

Obviously, when you apply this solution to your application and then you try to enter a property that you haven't specified when defying the request, the client-side object model will generate a "PropertyOrFieldNotInitializedException" exception.

COMPerformance3

 

If you use these solutions, especially when you deal with a big amount of data in SharePoint 2010, you will see that your applications have shorter waiting time and a more efficient interaction and usability for the final user.