Using the Minimal Download Strategy with SharePoint 2013 Apps

Scot Hillier

by Scot Hillier on 4/30/2015

Share this:

Article Details

Date Revised:

Applies to:
AngularJS, Development, MDS, Minimal Download Strategy, SharePoint 2013, single-page app, SPA

When creating applications based on JavaScript, developers must always be concerned about the amount of data moving between the client and server. Obviously, more data takes more time resulting in a degradation of the end user experience. One key area where data size should be managed is the transition between pages in the same app. Page transitions offer a significant opportunity to reduce traffic because many elements are common between pages in the same app so they should not be downloaded each time.

Developers have a couple of different approaches for reducing data downloads across page transitions. One approach is to create a single-page app (SPA) that is architected to load HTML views into a single page. This is the approach used by Angular JS apps. Another approach is to create an infrastructure that manages the pages deltas between transitions. This is the approach used by SharePoint 2013 through a feature known as the Minimal Download Strategy (MDS). You can take advantage of the MDS architecture when you are creating SharePoint-hosted apps.

When creating SharePoint apps, you can certainly decide to use either SPA or MDS architecture. Angular JS is a screaming-hot technology right now, so your instinct might be to just use a SPA. Because SharePoint 2013 itself is not a SPA, however, MDS can play an important role if you intend to use out-of-the-box SharePoint elements in your SharePoint-hosted app. Consider a SharePoint list, for example. If you enable MDS in your SharePoint-hosted apps, then you can use the out-of-the-box list user interface and keep MDS active. If you choose to write a SPA, then you will have to rewrite the list user interface to be compliant with your SPA architecture. While I am certainly a big fan of SPA architecture, in this article, I’ll show you how to use MDS in your SharePoint-hosted apps. You can find the code for this article in the IT Unity GitHub repo.

Enabling MDS in a SharePoint-hosted app

By default, SharePoint-hosted apps do not have MDS enabled. So, the first order of business is to enable MDS through the home page of the app. I’ll do this using a custom JavaScript module utilizing the client object model (CSOM). Listing 1 shows the core of the functionality, which first checks to see if MDS is enabled, and then enables it if required.

Listing 1, Enabling MDS

var MDS = window.MDS || {};
MDS.Utility = function () {
    "use strict";
    var site;
    var init = function () {
    var getMDS = function () {
        var ctx = new SP.ClientContext.get_current();
        site = ctx.get_web();
            function () {
                if (!site.get_enableMinimalDownload()) {
            function () {
    var setMDS = function () {
        var ctx = new SP.ClientContext.get_current();
        site = ctx.get_web();
            function () {
                console.log("Script Link added and MDS enabled");
            function () {
    return {
        init: init
(function () {

In order for MDS to work correctly, site pages must meet certain requirements to be MDS-compliant. If the page is not MDS-compliant, then MDS issues a “failover,” which causes a redirect to the full version of the page. Failovers are particularly wasteful because they cause an additional round trip to the server as well as bringing back additional data. According to MSDN, the following conditions will result in an MDS failover.

  • The new page has a different master page
  • The current master page has changed
  • CSS or script elements are present, which are not registered with MDS
  • Illegal HTML
  • The page contains noncompliant server controls

The most-likely way for your app to cause a failover is to include script tags in the page head. But, we need to include some bootstrap code in the app since MDS is not initially enabled. The answer is to use SharePoint scripts-on-demand (SOD) infrastructure and place the script tag at the end of the page body. The code in Listing 1 is contained in a library named app.js, which is loaded using SOD as shown in Listing 2. Note the script tag is in the body of the page by virtue of being contained in the PlaceHolderMain control.

Listing 2, Loading the initial library

<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
        SP.SOD.executeOrDelayUntilScriptLoaded(function () {
            SP.SOD.registerSod("app.js", "../scripts/app.js");
            SP.SOD.executeFunc("app.js", null, function () { });
        }, "sp.js");

Adding ScriptLinks to the app

Once MDS is enabled on the SharePoint-hosted app, then you’ll need to register your other JavaScript libraries with MDS so that they are available on every page without reloading. Registering your libraries involves programmatically creating a ScriptLink user custom action, registering a namespace, and creating an initialization function. The code in Listing 3 accomplishes all of this.

Listing 3, Registering custom JavaScript code with MDS

var ctx = new SP.ClientContext.get_current();
site = ctx.get_web();
var script1 = "" +
    "Type.registerNamespace('wingtip');" +
    "(function $_global_wingtip() {" +
    "  console.log('$_global_wingtip called');" +
    "  wingtip = function () {" +
    "    'use strict';" +
    "    var init = function () {" +
    "      console.log('wingtip.init called');" +
    "      return 'MDS is enabled on this page!';" +
    "    };" +
    "    return {" +
    "      init: init" +
    "    };" +
    "  }();" +
var userCustomActions = site.get_userCustomActions();
var scriptLink1 = userCustomActions.add();
scriptLink1.set_title("wingtip library");
    function () {
        console.log("Script Link added");
    function () {

The code in listing 3 creates a ScriptLink user custom action via an injected code block. Examining the code block, you will see that it uses the code Type.registerNamespace('wingtip') to register the namespace “wingtip” with MDS. The registration ensures that the wingtip namespace will be preserved between page loads so that any code contained within the namespace will be available. Libraries that are not registered in this manner are deleted from the global namespace during page transitions.

The code in listing 3 also defines a special initialization function named $_global_wingtip(). This naming standard is a convention that identifies the function as an MDS initialization function. MDS will call this function on page transitions if necessary to initialize the library. In the sample, the initialization function creates a single function named init that returns the text “MDS is enabled on this page!” The end result is that we can use the following code on any MDS-compliant page to call the init method without having to reload the wingtip library.

document.getElementById('message').innerText = wingtip.init();

Navigating MDS pages

Once you have enabled MDS and you have properly registered the code libraries, you can navigate between pages using MDS. MDS utilizes a client-side engine and a server-side engine to calculate the page’s changes and render the new page following navigation. The server-side processing is done by linking through the _layouts/15/start.aspx page followed by a hashtag indicating the target page. So, the links in your app need to follow this convention. If you add a page to your SharePoint-hosted app named page1.aspx, for example, then you can navigate to it using the following HTML. In the sample app, the page also runs the code block and displays the message indicating MDS is enabled.

<a href="../_layouts/15/start.aspx#/Pages/page1.aspx">Go to Page 1</a>

Additionally, you can navigate to built-in list pages through MDS. These pages are already MDS-compliant, so you don’t have to do anything special. The following HTML shows an example of a link navigating to an announcements list.

<a href="../_layouts/15/start.aspx#/Lists/Announcements">Announcements</a>

Once you have the navigation system set up, you can try out the app and see the effects of MDS on page loads. To test the app for this article, I deployed to an Office 365 developer tenant and used Fiddler to track the page loads. Initially MDS is not enabled, so the home page of the app is a full page load and required, which was 46K in size. After MDS was enabled, that number dropped to 38K – a 20% improvement. The out-of-the box list interface showed good results as well, going from 80K to 72K under MDS. And keep in mind, that these were very simple pages for testing. You can expect more complex pages to show even better results.

When you include a page in the MDS navigation, remember that it must not contain any elements that will cause a failover. As a test, I added an MDS-compliant page to my app and a page with a script tag that would cause a failover. The MDS-compliant page showed a petite size of 19K when loaded. The non-compliant page cost an initial 38K followed by a redirection and full-page load for another 46K. The total hit for the failover was a staggering 84K!


The Minimal Download Strategy can have a significant positive impact on page download sizes in multi-page SharePoint-hosted apps. Creating multi-page SharePoint-hosted apps also allows you to take advantage of built-in pages like SharePoint list views and forms while controlling download sizes. While JavaScript frameworks like Angular JS are excellent for building SPAs, sometimes a multi-page SharePoint-hosted app with list support is the right solution. So, consider MDS for use with your SharePoint-hosted apps.

Topic: Development

Sign in with

Or register