tags:

views:

1256

answers:

7

In an ASP.NET web app with a lot of HTML pages, a lot of inline Javascript functions are accumulating. What is a good plan for organizing them into external files? Most of the functions are particular to the page for which they are written, but a few are relevant to the entire application.

A single file could get quite large. With C#, etc, I usually divide the files at least into one containing the general functions and classes, so that I can use the same file for other applications, and one for functions and classes particular to this application. I don't think that a large file would be good for performance in a web application, however.

What is the thinking in this regard? Thanks Mike Thomas

+7  A: 

You probably want each page to have its page-specific JS in one place, and then all the shared JS in a large file. If you SRC the large file, then your users' browsers will cache the JS on the first load, and the file size won't be an issue. If you're particularly worried about it, you can pack/minify your JS src into a "distributable" form and save a few kb.

Adam Bellaire
+4  A: 

Single file is large but is cached. Too many small files mean more requests to the server. It's a balancing act. Use tools like Firebug and YSlow to measure your performance and figure out what is best for your application.

Ken
+4  A: 

There is some per-request overhead, so in total you will improve performance by combining it all into a single file. It may, however, slow down load times on the first page a user visits, and it may result in useless traffic if some user never require certain parts of your js.

The first of these problems isn't quite as problematic, though. If you have something like a signup page that everyone visits first and spends some time on (filling out a form, etc.), the page will be displayed once the html has been loaded and the js can load in the background while the user is busy with the form anyway.

I would organize the js into different files during development, i. e. one for general stuff and one per model, then combine them into a single file in the build process. You should also do compression at this point.

MattW.
+1  A: 

It also depends on the life of a user session. If a user is likely to go to multiple pages and spend a long time on the site a single large file can be worth the initial load seeing as it's cached. If it's more likely the user will come from google and just hit a single page then it would be better to just have individual files per page.

slashnick
+2  A: 

UPDATE: I explain this a bit more in depth in a blog post.

Assuming you mean .aspx pages when you indicate "HTML pages," here is what I do:

Let's say I have a page named foo.aspx and I have JavaScript specific to it. I name the .js file foo.aspx.js. Then I use something like this in a base page class (i.e. all of my pages inherit from this class):

protected override void OnLoad(EventArgs e)
{
   base.OnLoad(e);
   string possiblePageSpecificJavaScriptFile = string.Format("{0}.js", this.TemplateControl.AppRelativeVirtualPath);
   if (File.Exists(Server.MapPath(possiblePageSpecificJavaScriptFile)) == true)
   {
      string absolutePath = possiblePageSpecificJavaScriptFile.Replace("~", Request.ApplicationPath);
      absolutePath = string.Format("/{0}", absolutePath.TrimStart('/'));
      Page.ClientScript.RegisterClientScriptInclude(absolutePath, absolutePath);
   }
}

So, for each page in my application, this will look for a *.aspx.js file that matches the name of the page (in our example, foo.aspx.js) and place, within the rendered page, a script tag referencing it. (The code after the base.OnLoad(e); would best be extracted, I am simply trying to keep this as short as possible!)

To complete this, I have a registry hack that will cause any *.aspx.js files to collapse underneath the *.aspx page in the solution explorer of Visual Studio (i.e. it will hide underneath the page, just like the *.aspx.cs file does). Depending on the version of Visual Studio you are using, the registry hack is different. Here are a couple that I use with Windows XP (I don't know if they differ for Vista because I don't use Vista) - copy each one into a text file and rename it with a .reg extension, then execute the file:

Visual Studio 2005

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Projects\{E24C65DC-7377-472b-9ABA-BC803B73C61A}\RelatedFiles\.aspx\.js]
@=""

Visual Studio 2008

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Projects\{E24C65DC-7377-472b-9ABA-BC803B73C61A}\RelatedFiles\.aspx\.js]
@=""

You will probably need to reboot your machine before these take effect. Also, the nesting will only take place for newly-added .js files, any that you have which are already named *.aspx.js can be nested by either re-adding them to the project or manually modifying the .csproj file's XML.

Anyway, that is how I do things and it really helps to keep things organized. For JavaScript files containing commonly-used JavaScript, I keep those in a root-level folder called JavaScript and also have some code in my base page class that adds those references. That should be simple enough to figure out. Hope this helps someone.

Jason Bunting
+1  A: 
roosteronacid
A: 

I would recommend that if you split your JS into seperate files, that you do not use lots of tags to include them , that will kill page-load performance. Instead, use server-side includes to inline them before they leave the server.

skaffman
Inline scripts, however, are not cached by the browser, so this solution isn't so great after all...
Jason Bunting