Supported way of eliminating (large) JS files for SharePoint 2010


During an onsite visit at a customer who were very busy at creating an Internet facing website using SharePoint 2010,  I was asked if the technique that was described by my buddy Chris O’Brien to prevent the loading of unnecessary .js files was supported yes or not. And if not, if Microsoft had an alternative. Needless to say that the approach that Chris took was not really that supported by Microsoft (modifying the HttpContext and using Reflection are not really that great to be supporting right 😉

If you are really wondering what this post is about, I strongly recommend reading Chris’s post “Eliminating large JS files to optimize SharePoint 2010 internet sites“ on why you don’t want to load the all .js that are used by SharePoint 2010 files for anonymous facing websites.

How this stuff works within Microsoft?

However, it took some challenges to figure this one out. I would like to give you an insight how stuff works within Microsoft on how to get something like this be officially supported yes/no.
First of all, the only team responsible for saying that something is supported or not, is the Product Group (PG).

To get such a statement the following happens:

  • PFE (that’s me) researches if there is a related (kb) article to support the question of the answer, if nothing found, he escalates this to the Account Manager of the customer who then raises a ticket for a Request for Collaboration.
  • Technical Lead will craft a Request for Collaboration with the PG
  • RFC goes to an Escalation Engineer that maintains this communication with the PG
  • PG responds with an answer, while they are extremely busy with developing the next version of SharePoint
  • RFC goes back to the Escalation Engineer and he/she communicates this with the Technical Lead and the involved on-site engineer (that’s me) to see if the answer is the desired one

As you may have noticed, I (as a Premier Field Engineer) don’t have a direct line with the PG. It’s not that I can call the developer lead of the WCM piece of the platform to give me an answer to something like this or why something is implemented as it is, this is of course for good reason 😉
I just wanted to point out how many steps are involved and that such a process can take up quite the time to be finished.

 

The solution

Sorry to have keep you waiting, however, below is the code by utilizing Chris’s solution, to prevent the registration and downloading of the .js files.

protected override void OnPreRender(EventArgs e)

{

    if (!HttpContext.Current.User.Identity.IsAuthenticated)

    {

        this.Controls.Add(new LiteralControl("<script type='text/javascript'>SP.SOD.set_prefetch(0);</script>"));

    }

 

    base.OnPreRender(e);

}

There you have it, by just calling a (yet) undocumented SharePoint JSOM call, will result in SharePoint not loading and registering the .js files. This method is however a public API which you can use for this particular reason.
The only you need to make sure is that this control is near the bottom of the page and not on top of the page like Chris explains in his post.

Really?

Yes, really, this is the solution. The question is, what does it actually do?
Well, it just stops the prefetching from happening. The only time the .js files are loaded is when a control is asking for it, meaning that you really should test if everything still works on your page when implementing this and you use a control that is dependent on a SharePoint .js file. Furthermore there is maybe a performance penalty you need to pay when you are 'synchronously’ downloading that particular .js file.

Also, please make note, like Chris is also explaining in his post, it’s not just the downloading of the .js files that is the issue, it’s also the manipulating of the DOM that is being prevented which results in a page that is loaded quicker and feels ‘snappier’ as well.

As confirmed by both Chris O’Brien and Waldek Mastykarz who are (to me at least 🙂 the WCM gurus.


Comments (3)

  1. Dennis Gaida says:

    Thanks for the article! Had to read "JSOM call" three times only to understand you didn't mean JSON – don't we usually call it the Javascript client object model? At the very least your abbreviation is missing a "C" for client 😉

  2. Anu says:

    This is exactly what I want to do! However, I'm unable to get it working 🙁 Could you elaborate on all the steps to achieve this ? I'm new to SharePoint and .NET.

    I created an Empty SharePoint project, added the code to a class that derives from WebControl.

    namespace Test1ReduceJSDelegate

    {

       class Test1ReduceJSDelegateControl:WebControl

       {

           protected override void OnPreRender(EventArgs e)

           {

               if (HttpContext.Current.User.Identity.IsAuthenticated)            

                   this.Controls.Add(new LiteralControl("<script type='text/javascript'>SP.SOD.set_prefetch(0);</script>"));            

               base.OnPreRender(e);

           }              

       }    

    }

    –Elements.xml:

    <?xml version="1.0" encoding="utf-8"?>

    <Elements xmlns="schemas.microsoft.com/…/">

    <Control Id="AdditionalPageHead"  Sequence="10" ControlAssembly="$SharePoint.Project.AssemblyFullName$" ControlClass="Test1ReduceJSDelegate.Test1ReduceJSDelegateControl"></Control>

    </Elements>

    –Feature1.Template.xml

    <?xml version="1.0" encoding="utf-8" ?>

    <Feature xmlns="schemas.microsoft.com/…/"  ReceiverAssembly="$SharePoint.Project.AssemblyFullName$" ReceiverClass="Test1ReduceJSDelegate.Test1ReduceJSDelegateControl" Description="Reducing JS calls" Version="1.0.0.0" Hidden="FALSE" DefaultResourceFile="core" Id="5114b9c0-0e26-42ef-8c28-a9831a3807fb" Scope="Web" Title="Feature-JSReduce">

    <ElementManifests>

    <ElementManifest Location="Test1ReduceJSDelegateFeatureElements.xml" />

    </ElementManifests>

    </Feature>

    However, this just doesn't work. I see the same number of JS calls. ULS logs show errors:

    –Missing one or more of the following attributes from the root node in solution test1reducejsdelegate.wsp: assembly '', type ''.

    –The configuration database was queried for a non-existent object with the id 5114b9c0-0e26-42ef-8c28-a9831a3807fb. Most commonly, this is caused by removing an SPFeatureDefinition without writing upgrade code to remove references to the feature from each site.

    Thanks!

  3. Serge van den Oever [Macaw] says:

    And if you really want to make your internet facing SharePoint website fly and not only load less Javascript but also generate perfect HTML have a look at DualLayout (weblogs.asp.net/…/default.aspx).

    Robin, was gezellig gisteren op de Blackbelt meeting! Waldek, waar was je?

Skip to main content