Main menu

Post navigation

SharePoint optimized – part 1, CSOM calls

Intranet home page should contains all information that are needed in daily manner. In fact many companies use home page as a traffic node where everybody comes just to find a navigation link pointing to another part of intranet. In my current company, Findwise, we do that too. However one of our components that allows us to quickly navigate through intranet sites gets slower and slower year by year. Currently it’s loading time is almost 10 seconds! I decided to fix it or even rebuild it if needed. Especially that few weeks ago on ShareCon 365 conference I talked about SharePoint Framework in Search Driven Architecture where I described the customer case, PGNIG Termika, who saved about 600k PLN (~$165.000) per year thanks to their information accessibility improvements (information time access dropped from 5-10 minutes to 1-2 seconds).

In this post I wanted to show you what was the problem, how I fixed it and how my fix cuts the component loading time 6 times!

Navigate through customers and projects

In Findwise we are using SharePoint in a common pattern for keeping customer/project related data in one well-organized place: for every customer we create a subsite. Then for every project of a customer we’ve created a subsite in his site. To be able to quickly navigate through customers and their projects few years ago we built a component and put it on our home page. It look like this:

It’s a tree view with list of customers. In above component when user click on some customer name he will be redirected to that customer site. When a user click on plus button the customer projects sites will be showed and by clicking on project name user can navigate to its site. Like below:

Moreover it has simple search box that allows for searching through customers (but not projects, I’ll explain that later). We didn’t want to spend too many hours for a simple tool so we basically just use simple HTML, JS and CSS loaded by Script Editor Web Part. For fetching site information (name, url) we used JSOM (CSOM in JS).

Wrong usage of CSOM for aggregation may cause performance issues

At the time the component was developed it was good enough. However when customers and projects grow in number it started to slow down. In order to fix it I needed to know what was the problem. I opened browser Dev tool > network tab and I saw this:

Red line on timeline indicates when JSOM query begins. Ok, somehow I expected that it will be related to query but needed to be 100% sure before I get into the code. It also explains why the component does not preload projects for customers: if loading around 500 customers took ~10 second (averaged after 10 tests) then making another JSOM call for customer projects (which gives us extra 500 requests) will take ages.

I checked original code and cannot find anything that would catch my attention.

Explanation is unpredictability of async calls end. In the code above we tried to load different subsites (i.e. for CustomerA site and CustomerB site) to the same variable (projectSubsites) and then load it in success method – but since we cannot predict when particular callback will return there may be (and will be) situation when:

immediately after it (that’s how async works, right?) there is initialization for loading projects sites but for CustomerB to the same variable

at some point similarOnRequestSucceeded fires for CustomerA and tries to get information from projectSubsites…which has been overridden by step 2 so it’s still not initialized -> Error collection not initialized.

So we have 2 options:

Create a new variable for every subsite crawl

Create anonymous success function dynamically

Since I don’t like to reinvent the wheel I go for option 2 – there is cool gist enumWebs.js that do exactly what we need – recursively crawl all site subsites. I modified in a little bit in order to put any site as a root and it looks like below: