Combining javascript files with Ajax toolkit library


One of the new features that came with .NET Framework SP1 is the ability to combine multiple js files in order to reduce the number of files downloaded by the browser.

In theory, you simply have to list all the JS files called by the page in a sub section of the script manager. You can get the list of files needed by your page by using the script reference profiler (third party control that lists all the files). You can find this control on http://weblogs.asp.net/bleroy/archive/2008/06/12/script-reference-profiler.aspx

Once the list is known, you just need to copy/paste it in the Script Manager control using the new ‘CompositeScript’ tag. This is an example from a real world application using Telerik and AJAX toolkit controls.

 <asp:ScriptManager ID=”ScriptManager1″ runat=”server”>
<CompositeScript ScriptMode=”Release”>
<Scripts>
<asp:ScriptReference name=”MicrosoftAjax.js”/>
<asp:ScriptReference name=”MicrosoftAjaxWebForms.js”/>
<asp:ScriptReference name=”AjaxControlToolkit.Common.Common.js” assembly=”AjaxControlToolkit, Version=3.0.20229.17016, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e”/>
<asp:ScriptReference name=”AjaxControlToolkit.ExtenderBase.BaseScripts.js” assembly=”AjaxControlToolkit, Version=3.0.20229.17016, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e”/>
<asp:ScriptReference name=”Telerik.Web.UI.Common.Core.js” assembly=”Telerik.Web.UI, Version=2008.2.826.35, Culture=neutral, PublicKeyToken=121fae78165ba3d4″/>
<asp:ScriptReference name=”Telerik.Web.UI.Common.Animation.AnimationScripts.js” assembly=”Telerik.Web.UI, Version=2008.2.826.35, Culture=neutral, PublicKeyToken=121fae78165ba3d4″/>
<asp:ScriptReference name=”Telerik.Web.UI.Common.Scrolling.ScrollingScripts.js” assembly=”Telerik.Web.UI, Version=2008.2.826.35, Culture=neutral, PublicKeyToken=121fae78165ba3d4″/>
<asp:ScriptReference name=”Telerik.Web.UI.Common.Navigation.NavigationScripts.js” assembly=”Telerik.Web.UI, Version=2008.2.826.35, Culture=neutral, PublicKeyToken=121fae78165ba3d4″/>
<asp:ScriptReference name=”Telerik.Web.UI.Menu.RadMenuScripts.js” assembly=”Telerik.Web.UI, Version=2008.2.826.35, Culture=neutral, PublicKeyToken=121fae78165ba3d4″/>
<asp:ScriptReference name=”Telerik.Web.UI.ComboBox.RadComboBoxScripts.js” assembly=”Telerik.Web.UI, Version=2008.2.826.35, Culture=neutral, PublicKeyToken=121fae78165ba3d4″/>
<asp:ScriptReference name=”Telerik.Web.UI.TabStrip.RadTabStripScripts.js” assembly=”Telerik.Web.UI, Version=2008.2.826.35, Culture=neutral, PublicKeyToken=121fae78165ba3d4″/>
</Scripts>
</CompositeScript>
</asp:ScriptManager>

Note that you can add references to your own JS files using the path to the Javascript:

i.e: <asp:ScriptReference Path=”~/js/MyJavascript.js” />

 However, this example won’t work properly. As you try to run a page that contains it, you will get the following error message:

The resource URL cannot be longer than 1024 characters. If using a CompositeScriptReference, reduce the number of ScriptReferences it contains, or combine them into a single static file and set the Path property to the location of it.

To fix this issue, you should split the list into smaller chuncks and add them in different Proxy Script Manager controls. Bear in mind that each of these controls will generate a separate JS file and therefore you may end up with as many JS files as the number of Script Manager/Proxy Script Manager controls.

<asp:ScriptManagerProxy ID=”ScriptManagerProxy1″ runat=”server”>
<CompositeScript ScriptMode=”Release”>
<Scripts>

…. SCRIPT References….(subset)
</Scripts>
</CompositeScript>
</asp:ScriptManagerProxy >

<asp:ScriptManagerProxy ID=”ScriptManagerProxy2″ runat=”server”>
<CompositeScript ScriptMode=”Release”>
<Scripts>

…. SCRIPT References….(another subset)
</Scripts>
</CompositeScript>
</asp:ScriptManagerProxy >

Another issue you should pay attention to is the order of your custom JS files. If you have any of your files that has Javascript code that executes at load (not in a function) and in which you use some Ajax functionality, ensure that you download it after the Ajax files. In other words, ensure that all Ajax library JS files are referenced before yours. I suggest that you put all your files in a separate Proxy Script Manager to isolate them and put this section as the last one in the list.

By combining files you create a new file with a URL that contains the references of all the JS included in the new resource (that’s the reason why it is limitted to 1024 characters in the URL). That’s said, you better have always the same sections with the same files in the same order so that the browser will download them only once and cache them for future use. I think that it is better to download a larger file than needed rather than redownloading many times the needed part only.

My suggestion is to put all references to common Ajax library files in multiple sections of the script manager and subsequent proxy script managers and put all this list in a/multiple user controls that you’ll add to your pages. Custom scripts should be added separately as needed or listed in one Proxy Script Manager and shared across all pages if you don’t have that many files.

As it is highly recommended to load javascripts at the end of the page, I suggest that you keep your ScriptManager empty of any JS reference and put all your references in ScriptManagerProxy controls placed at the end of the page.

Advertisements

9 thoughts on “Combining javascript files with Ajax toolkit library

  1. Hi Samir,

    Thanks for the work around. I just went through a process of converting a bunch of control logic to take advantage of the SP1 CompositeScript feature and ran into this issue.

    Another frustrating part of the Composite Script feature in SP1.

  2. Thanks for this article,

    The resource URL cannot be longer than 1024 characters. If using a CompositeScriptReference, reduce the number of ScriptReferences it contains, or combine them into a single static file and set the Path property to the location of it.

    How we can resolve this issue with CompositeScript without using multiple ScriptManagerProxy controls on a page.

    Thanks

    • Hi Amit,

      You can definitely create one single file that contains all your JS files and reference it. Though, it may be difficult to apply the same principle for the JS files referenced by the AJAX Toolkit controls for instance (or Telerik controls if you use them) because these files are embeeded in the assemblies and if they are not referenced explicitly, they will be added by the SCRIPT Manager as needed which will result in different dynamic JS files different from one page to another and which will require a reload of these files for each page that needs them. That’s the reason why you better create a ‘common set’ of files that will be loaded once and then eventually, you may keep few separate JS files that will be loaded only on a very small set of pages (generally, a JS that is used only in one page).

      To dynamically combine JS files (at run time it picks up all JS files in a folder or in a section of your configuration file) check this link http://www.codeproject.com/KB/aspnet/CssAndJavaScriptOptimizer.aspx?display=PrintAll&fid=1536291&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2946209

      Cheers,

  3. Pingback: 10 simple rules to write better ASP.NET applications « Samir Bellouti

  4. Pingback: How to improve AJAX page Speed with 5 easy steps « Asp.net & Sql server fundas with Rajat Jaiswal

  5. Is it possible to have AJAX enabled WCF generated javascript file reference inside the CompositeScript tag?

    JS generated something like mywcfservice.svc/js

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s