Rewatching the Windows Phone Application Performance MIX10 talk by Jeff Wilcox, I took a note of one particular part where he clearly answers a question I’ve been asked a few times by now already. This question is based around the confusing statement that Pivot controls are supposed to be lazy loading their content pages, in contrast to Panoramas, which, at startup, would load all pages at once. The part that confuses developers the most is that when they start debugging their apps, they find out that Pivots load all their pages at startup too! How come? Aren’t Pivots loading pages only when needed?
Jeff explains this very clearly (fast forward to approx. minute 25) : “So the instant you go to a page, we pop up the Pivot, we’ll load the content there. … … Trouble is, we need to load more, because we want to provide a smooth experience when you pivot around. So we’re actually also loading, right after that first page comes up, we’ll kick off a load for both items on the left and the right.”
See Jeff’s talk on the Channel 9 site.
What this means is that if your Pivot has only 2 or 3 pages, the startup performance won’t be that much different than when using a Panorama. If those 3 content pages are heavy on the load, use a lot of bindings etc., you can get into trouble. In some cases, loading a single content page on startup (and the rest when pivoted to) might actually result in a better experience than preloading all 3 pages.
Is there a way to override the default Pivot behavior and load only one content page on startup?
Of course there is.
The trick is to create a user control for each content page (which is a good idea anyway) and start it off with a Pivot control by specifying empty pages:
<controls:Pivot Title="My Pivot" LoadingPivotItem="OnLoadingPivotItem"> <controls:PivotItem Header="Page 1" /> <controls:PivotItem Header="Page 2" /> <controls:PivotItem Header="Page 3" /> </controls:Pivot>
The LoadingPivotItem event will fire each time the Pivot would load a new content page. From MSDN documentation: “[LoadingPivotItem is an] Event for offering an opportunity to dynamically load or change the content of a pivot item before it is displayed.”
What you do during this event is check whether the content is loaded yet and if it isn’t, kick off the load. Something like:
private void OnLoadingPivotItem(object sender, PivotItemEventArgs e) { if (e.Item.Content != null) { // Content loaded already return; } Pivot pivot = (Pivot)sender; if (e.Item == pivot.Items[0]) { e.Item.Content = new Page1Control(); } else if (e.Item == pivot.Items[1]) { e.Item.Content = new Page2Control(); } else if (e.Item == pivot.Items[2]) { e.Item.Content = new Page3Control(); } }
One thing to have in mind though: make sure that any data you want to display on those content pages are loaded on the background thread (again – always a good idea) to allow the pages to load as quickly as possible.