Batch JavaScript Libraries for Increased Performance

Date Published: 28 July 2008

Batch JavaScript Libraries for Increased Performance

I’ve been meaning to set up batched loading of the JavaScript libraries used by Lake Quincy Media’s administration application for some time, and finally had a chance this past weekend. The site uses a variety of third-party tools such as DevExpress,ComponentArt,AJAX Control Toolkit,Overlib,PeterBlum,Dundas Charts, and probably a couple of others I’m forgetting at the moment. As a result, the site’s initial load tended to be pretty sluggish. JavaScript libraries are loaded and executed serially by the browser, resulting in a pretty significant bottleneck to page load time, as shown here

Once loaded the first time, most of these scripts are cached in the client, so performance doesn’t remain dreadful (and usually the individual files don’t take as long as they are above). However, you can see how this has a seriously detrimental effect on the site’s perceived performance, and this has nothing to do with any kind of server or database processing time (which is typically the first place folks go looking for performance issues within ASP.NET applications).

While researching this problem I found a couple of helpful links:

More importantly, though, I discovered that the AJAX Control Toolkit project added a new ScriptManager object over a year ago that I’d overlooked. David Anson blogged about the new ToolkitScriptManager class last June, explaining its script combining features. Replacing my ScriptManager with this one resulted in an immediate and significant reduction in the number of ScriptResource.axd calls required. The ToolkitScriptManager inherits from ScriptManager, so you simply need to replace <asp:ScriptManager /> with <ajaxToolkit:ToolkitScriptManager /> assuming your prefix for the AJAX Control Toolkit is ajaxToolkit.

It’s a good idea to use a separate domain for static files like images, CSS, and common scripts, because browsers typically will open 2 concurrent connectionsper domainto retrieve such things. However, in the case of scripts like these, the browser only loads them one at a time, and further since they’re dynamic (at least, the *.axd ones), there’s no simple way to use a separate domain anyway.

After switching to ToolkitScriptManager, I still had a bunch of dynamic script calls, which I determined were being loaded by ComponentArt controls. I figured they probably had a similar batch load mechanism, and they did not disappoint. Milos wrote about Optimizing Web.UI Client Script Deployment, which has the necessary steps. It requires setting up a handler and adding a key to (something which I think is a bad idea for components to use), but otherwise it was quite painless.

Finally, I determined that the Overlib scripts we’re using were only needed by one custom control we’d created for displaying Help dialogs, but the scripts were being included in the Master page. Many pages show the help dialogs, but many do not, and there were 4 separate scripts being loaded. I could have written my own handler or updated the custom control to automatically emit the required script references, but since I was going for the simplest thing that worked I opted to wrap the 4