Question

I have found that page loads in SharePoint 2013 Online (have not tested On-prem) falls back from MDS to the full page load for any page which contains an app part.

I have found this to be true for both SharePoint hosted app parts and provider hosted app parts.

I have simplified the pages to remove all but just basic html content to be sure some of the known issues, like script links, are not causing the issue.

As part of my testing, I confirmed that MDS is functioning for other pages on the site (ex: Navigating from one document library to another).

I have read a few articles about MDS fallback,

but I haven't seen anyone mention that app parts will cancel MDS.

Here a couple posts that I found useful.

http://steve.thelineberrys.com/gotchas-using-custom-web-parts-and-the-minimal-download-strategy/ http://www.wictorwilen.se/sharepoint-2013---introduction-to-the-minimal-download-strategy-mds

Edit: I created a fiddler trace of the MDS fallback. I don't see any errors generated as part of the responses. The trace can be downloaded at http://1drv.ms/1pWrlx3.

Was it helpful?

Solution

Ok, that fiddler trace helps out a lot. You have script in your HTML which is causing the page to revert out of MDS mode.

The code below is the culprit. It is displayed right above the iframe for your app part. You will need to register that code in your code behind using SPPageContentManager.RegisterClientScriptBlock.

<script type='text/javascript'>
    var spAppIFrameSenderInfo = new Array(1);
    var SPAppIFramePostMsgHandler = function(e)
    {
        if (e.data.length > 100)
            return;

        var regex = RegExp(/(<\s*[Mm]essage\s+[Ss]ender[Ii]d\s*=\s*([\dAaBbCcDdEdFf]{8})(\d{1,3})\s*>[Rr]esize\s*\(\s*(\s*(\d*)\s*([^,\)\s\d]*)\s*,\s*(\d*)\s*([^,\)\s\d]*))?\s*\)\s*<\/\s*[Mm]essage\s*>)/);
        var results = regex.exec(e.data);
        if (results == null)
            return;

        var senderIndex = results[3];
        if (senderIndex >= spAppIFrameSenderInfo.length)
            return;

        var senderId = results[2] + senderIndex;
        var iframeId = unescape(spAppIFrameSenderInfo[senderIndex][1]);
        var senderOrigin = unescape(spAppIFrameSenderInfo[senderIndex][2]);
        if (senderId != spAppIFrameSenderInfo[senderIndex][0] || senderOrigin != e.origin)
            return;

        var width = results[5];
        var height = results[7];
        if (width == "")
        {
            width = '300px';
        }
        else
        {
            var widthUnit = results[6];
            if (widthUnit == "")
                widthUnit = 'px';

            width = width + widthUnit;
        }

        if (height == "")
        {
            height = '150px';
        }
        else
        {
            var heightUnit = results[8];                        
            if (heightUnit == "")
                heightUnit = 'px';

            height = height + heightUnit;
        }

        var widthCssText = "";
        var resizeWidth = ('False' == spAppIFrameSenderInfo[senderIndex][3]);
        if (resizeWidth)
        {
            widthCssText = 'width:' + width + ' !important;';
        }

        var cssText = widthCssText;
        var resizeHeight = ('False' == spAppIFrameSenderInfo[senderIndex][4]);
        if (resizeHeight)
        {
            cssText += 'height:' + height + ' !important';
        }

        if (cssText != "")
        {
            var webPartInnermostDivId = spAppIFrameSenderInfo[senderIndex][5];
            if (webPartInnermostDivId != "")
            {
                var webPartDivId = 'WebPart' + webPartInnermostDivId;

                var webPartDiv = document.getElementById(webPartDivId);
                if (null != webPartDiv)
                {
                    webPartDiv.style.cssText = cssText;
                }

                cssText = "";
                if (resizeWidth)
                {
                    var webPartChromeTitle = document.getElementById(webPartDivId + '_ChromeTitle');
                    if (null != webPartChromeTitle)
                    {
                        webPartChromeTitle.style.cssText = widthCssText;
                    }

                    cssText = 'width:100% !important;'
                }

                if (resizeHeight)
                {
                    cssText += 'height:100% !important';
                }

                var webPartInnermostDiv = document.getElementById(webPartInnermostDivId);
                if (null != webPartInnermostDiv)
                {
                    webPartInnermostDiv.style.cssText = cssText;
                }
            }

            var iframe = document.getElementById(iframeId);
            if (null != iframe)
            {
                iframe.style.cssText = cssText;
            }
        }
    }

    if (typeof window.addEventListener != 'undefined')
    {
        window.addEventListener('message', SPAppIFramePostMsgHandler, false);
    }
    else if (typeof window.attachEvent != 'undefined')
    {
        window.attachEvent('onmessage', SPAppIFramePostMsgHandler);
    }spAppIFrameSenderInfo[0] = new Array("EC5C9C4B0","g_8282237a_000e_4ab0_baf6_a4ad64ccc6ba","http:\u002f\u002fapp-bda070359d354c.apps","False","False","ctl00_ctl33_g_1581e83c_d38c_4be0_81eb_1015c2ac7a1b");
</script>

OTHER TIPS

I found the following article from by Sean Hesters addressing this topic to be very helpful in answering this question for me: Working with and around SharePoints MDS

...if you are developing SharePoint 2013 App Parts for SharePoint-Hosted or Provider-Hosted solutions, the MDS story for now is bleak. At the time I’m writing this, the control used by SharePoint to render embedded App Parts on a page causes MDS to fail: Every. Single. Time. Not only does it fail, but the failure appears to be caused by SharePoint’s internals; there’s no way to resolve this by making App Parts MDS compliant. We dug into the SharePoint 2013 source using .NET Reflector and discovered that the SPAppIFrame control used to render App Parts emits a raw tag using the HtmlTextWriter class. This makes the SPAppIFrame control non-MDS compliant per Microsoft’s own recommendations listed above. You can find detailed technical information about this issue in my colleague Eric Bowden’s StackOverflow post on the subject. ThreeWill has a support ticket open with the SharePoint Online team to investigate this issue, but it probably won’t be an easy fix, so we don’t expect a resolution anytime soon. Unfortunately, this doesn’t leave many options for Hosted Solution developers for now:

  1. Use Apps instead of App Parts.
  2. Avoid routing requests to non-MDS-compliant pages through start.aspx.
  3. Disable the MDS feature on your SharePoint web.

So basically you can't do that. If you have to have App parts in your sites pages you are better off just disabling Minimal Download Strategy (MDS) as MDS will force that to occur anyway after it runs in your page.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top