ASP.NET MVC: How to combine scripts and other resources
ASP.NET pages that use AJAX components make usually many requests to server per one page to load all required JavaScript and CSS files. Connections, like all other real time resources, are most expensive to create and keep. If we can somehow decrease the number of requests per page load then we need less server resources for same amount of users. For ASP.NET forms we can use script combining, for ASP.NET MVC applications we can use ASP.NET MVC Client-side Resource Combine.
MVC Resource Combine is open-source project you can find in CodePlex. ASP.NET official ScriptManager needs server-side form as a container. This means that all scripts are loaded in the body of page. I have found no way how to make ScriptManager to create script and other references to page header. MVC Resource Combine is free of this problem.
MVC Resource Combine is easy to use. Just follow these steps.
- Download the latest release and add references to DLL-s of MVC Resource Combine.
- Add the following line to web.config file, under <configSections> element:
<section name="resourceCombine" type="Mvc.ResourceCombine.ConfigSectionSetting,
Mvc.ResourceCombine" />
- Add the following line to web.config file, under <configuration> section:
<resourceCombine definitionUrl="~/App_Data/combine.xml" />
- Now open Global.asax and add the following line before all the other route definitions:
routes.AddResourceCombineRoute("Resource Combine");
- To App_Data folder add new XML-file combine.xml. By example, for jqGrid you may have JavaScript resource set like this:
<?xml version="1.0" encoding="utf-8" ?>
<resourceCombine url="~/combine.axd" defaultDuration="15"
defaultVersion="1" ><resourceSet name="jqGrid" type="js" duration="30"
version="a"><resource path="~/Scripts/jquery-1.3.2.js"
mode="LocalStatic" /><resource path="~/Scripts/jquery.jqGrid.js"
mode="LocalStatic" /><resource path="~/Scripts/js/jqModal.js"
mode="LocalStatic" /><resource path="~/Scripts/js/jqDnR.js"
mode="LocalStatic" /><resource path="~/Scripts/jquery.ajaxQueue.js"
mode="LocalStatic" /><resource path="~/Scripts/jquery.bgiframe.min.js"
mode="LocalStatic" /><resource path="~/Scripts/thickbox-compressed.js"
mode="LocalStatic" /><resource path="~/Scripts/jquery.autocomplete.js"
mode="LocalStatic" /></resourceSet>
</resourceCombine>
- Now open Site.Master and add call for MVC Resource Combine and specify resource set by its name (jqGrid):
<%= Html.CombinerLink("jqGrid")%>
- Now run your application and view page source. You should see something like this:
<script type="text/javascript" src="/combine.axd/jqGrid/a">
</script>
NB! Don’t forget to add reference to Mvc.ResourceCombine namespace in your Global.asax and Site.Master files. Well, if you have Resharper, then it is almost possible to forget these references. :)
Now, let’s see results. It’s Saturday and I’m watching Estonian biggest song contest, so I’m too lazy to add Firebug screenshots here. I have a little bit different configuration but numbers in the following table should give you some idea about wins in performance.
Before
combine |
After
combine |
Difference
(before/after) |
|
Requests | 21 | 4 | 5.25 |
Size (kb) | 259 | 19 | 13.63 |
Time (s) | 7.69 | 4.84 | 1.59 |
As you can see, using MVC Resource Combining it is possible to achieve better performance with pretty simple and time consuming efforts. Also you don’t have to mix ScriptManager and other ASP.NET forms elements to your ASP.NET MVC views. By the way, you can combine also all the other resources that can be downloaded as one file – by example, style sheets.