views:

732

answers:

2

I'm looking at improving the performance of page load and render time of a rather complex ASP.NET site.

Due to the use of a lot of ASP.NET controls that themselves include javascript files (by simply using the script-tag) certain pages load the same javascript up to 10 times. Additionally, some javascript must be loaded early in the page, while others is better included at the end. Some I would like to dynamically load after the onload event instead of explicitly include in the page.

The way I'm thinking about is to let all the different controls register their need of a particular javascript file in a central place that in turn controls the generation of script-tags (thus avoiding duplicates) and where they are inserted into the generated output. This would also make it easy to dynamically switch between minified and full javascript files (e.g. appending debug=true to the query string would make files load by filename.debug.js instead of filename.compressed.js).

Using this solution it would also be possible for it to basically generate a javascript array of filenames that are used by a custom onload javascript function to dynamically load the scripts.

What is the best way to accomplish this? Use or extend something like ScriptManager, make a custom Control, override the Page object?

+1  A: 

In the control's Page_Load method, you can register your javascript for output (after confirming that it's not already registered).

E.g.,

ClientScriptManager script = Page.ClientScript;
if (!script.IsClientScriptIncludeRegistered("AlertHello"))
{
    script.RegisterClientScriptInclude("AlertHello", "Public/AlertHello.js");
}

NOTE: You can use .RegisterClientScriptBlock() if you want to have a block of JS instead of a separate file.

However, this outputs the script tag soon after the opening of the page's form tag. To output your script near the end of the page (i.e., just prior to the closing of the form tag), use the .RegisterStartupScript() methods.

ClientScriptManager script = Page.ClientScript;
if (!script.IsStartupScriptRegistered("StartupAlert"))
{
    script.RegisterStartupScript(this.GetType(), "StartupAlert",
           "<script type='text/javascript' src='Public/Alert.js'></script>");
}

Supposing that you absolutely need it in a specific place, however, you could add a static (or "shared" in VB.NET) read-only property that returns the script tag, and a boolean property that tells the control whether to output the script tag. In that case, in your ASPX, you could do something like...

<body>
  <!-- any place -->
  <uc1:myControl ID="myControl1" runat="server" jsOutput="False" />
  <!-- elsewhere -->
  <asp:Literal ID="litJS" runat="server" OnLoad="litJS_Load" />
</body>

Then program litJS_Load to set the sender's Text property to the string returned by the static property of the myControl class.

David
A: 

As mentioned using the script registration via the controls' Load event is a good idea, if they are compiled controls, you can also reference them as an embedded resource... If you are using ASP.Net Ajax, you can use the ScriptManager which can merge scripts within your page into one contiguous block for download.

Yahoo has a lot of information regarding script performance as well, the advice for this is also included in the YSlow extension for Firefox, which extends firebug.

In addition to having the scripts as an external resource, you should enable compression on the server, which can reduce download of various scripts. Not to mention minification of included scripts.

Tracker1