A question that comes up often is why SharePoint takes so long to do anything the first time something’s accessed after an IIS restart, or machine reboot.
Typically for a non-technical person this is what triggers this question:
- A page is opened in the browser by the user.
- SharePoint takes its’ sweet time getting said page.
- SharePoint finally sends the damned page, and normally sends it faster the next time so this isn’t a huge problem.
Not a huge problem normally as again, this is just a first-hit problem, but people have wondered why. Hopefully I’ll be able to explain to some extent why.
Waiting for SharePoint to load…
What Does SharePoint Do That Takes So Long?
First we have to understand what actually is loaded when we do something in SharePoint for the first time. In the case of the “load page” example, just about all areas of SharePoint are initialised so it tends to have the maximum first-load lag time.
SharePoint though is made up of lots of processes; IIS content processes, service-application processes, the timer service process, etc, etc. To give you an idea of what can happen per process, here’s some of the loading activities that take place (colour-coded to make it easier to see what’s going on):
1. To initialise any SharePoint process (be it something in IIS, PowerShell, or whatever):
- ULS initialisation (the logging system).
- Load XML configuration files of joined farm.
- Load & JIT SharePoint assemblies.
- Construct farm topology from configuration to figure out what we’re even part of.
2. To initialise any IIS process:
- Initialise new SharePoint IIS worker process
- + “initialise any SharePoint process”
- Initialise IIS pipeline & process HTTP request: load & JIT IIS base modules (ISAPI, security, caching, logging, etc) + SharePoint modules (SPRequestModule, PublishingHttpModule etc)
3. To initialise SharePoint content-page:
- Initialise new IIS SharePoint process.
- + “initialise any IIS process”
- Load SPSite & SPWeb for page
- + “initialise SharePoint object-model”.
- Initialise publishing object cache (100mb normally)
- Get page contents from content-database on SQL Server; compile & JIT page source.
- You may have seen the scope “EnsureListItemsData”; this is basically getting stuff from the content-database, and pages are no different.
- Get page web-parts from content-database too; compile & JIT dependant assemblies.
- Depending on page functionality, call SharePoint service applications WCF endpoints – taxonomy, user profile, search, etc
4. To initialise SharePoint object-model (to get a SPWeb, SPSite etc)
- Load web-application configuration (content-databases)
- Check upgrade status of each content-database to make sure we’re not going to brick our content queries.
- Authenticate user with STS & get security token for user.
The problem is normally that when you load a page, you’re actually doing all of the above several times, probably without actually realising it. Let’s see:
Load publishing page “home.aspx”
Opening a typical SharePoint homepage for the 1st time will do the following:
1. Call step 3 to load content-page. Load all of that up + dependencies (steps 2, 1, and 4) – this’ll take some time.
- One web-part needs user profile info to get audience data to know whether to show a web-part. Better call the user-profile service.
- Doh! That just started-up a new user-profile IIS process, hang on (load steps 2,1, and 4 again for another process) …
- We also need search too for a “what’s popular” web-part; better call that service too...
- What’s that? Search service-call application (not the search service itself; just the search service endpoint) isn’t warmed-up yet? Better run steps 2, and 1 another time for yet another process before we get a response back…
- Same for managed-metadata; need to call that service-app for this page to load the navigation fully …
- It’s not been called yet; surprise! Looks like we need to spawn another IIS application, running steps 1 & 2 for yet another worker-process.
- Security-token service is a must too, no matter what the page has. That’s another SharePoint IIS worker-process to fire-up.
- …more stuff? Depends on the page, but you get the idea.
All in all, a single HTTP “GET” to a page can spawn easily 5-6 IIS isolated worker-processes:
…each one needing its own copy of “SharePoint” in memory, and that’s just IIS. On top of that we have AppFabric distributed caching service, search topology, SharePoint timer services and more.
How to Reduce the Start-up Time?
In fairness, starting up SharePoint is becoming an increasingly rare thing to do. Back in the day, SharePoint solutions needed to restart the web-application IIS pool each deployment but no more (although plenty of people still use this prehistoric deployment method); since then we’ve got the sandbox service, and now client-side programming which don’t require any IIS app-pool restarts at all.
But anyway, if you want to reduce the load-time then just use team-sites with no user-profile, search or any other functionality. For developing most web-parts for example that’s all I use and because there’s no service-application dependency, any restarts needed are pretty quick.
SharePoint “light” if you really have to recycle app-pools.
// Sam Betts