views:

285

answers:

4

Although I am almost certain the answer to this question will be browser specific, do any of the browsers define behavior for when multiple <script> tags are used and have the same src attribute?

For instance...

<script src="../js/foo.js"></script>
...

<!-- what happens here? -->
<script src="../js/foo.js"></script>

The reason I ask this question in the first place, is that in my particular case I am using partial views in an ASP.NET MVC application which make use of JQuery. The JQuery JS file(s) are all included in the master template file via script tags. I would prefer to add script tags to the partial view files so that in case they are used outside the context of the master template, they will automatically include all the necessary JS files, and not rely on another view or template to include them. However, I certainly don't want to cause JS files to have to be transferred to the client multiple times, or any other side effects that could negatively impact the user experience.

My thinking right now is that most, if not all, of the major browsers (FF, Safari, IE, Opera) will cache a JS file the first time it is used, and then on subsequent script tags the browser will use the cached copy if available and if it hasn't expired. However, caching behavior can usually be altered through browser configuration, so it doesn't seem too "safe" to rely on any kind of caching behavior.

Will I just have to accept the fact that my partial views are going to have be dependent on other templates or views including the appropriate JS files?

+2  A: 

Even if they're cached, you may have problems since the same code will be executed twice. At the very least, this will cause the browser to take more time than necessary. And it may cause errors, since most JavaScript code isn't written to be executed twice. For example, it may attach the same event handlers twice.

JW
+1 some libraries are protected against double-inclusion, but as far as I can see jQuery is not. Don't include it twice. You can get unusual behaviours when libraries are instanced twice.
bobince
Code is executed when it is called. You meant to say it will be interpreted twice, which is quite different, and that produces problems different than you illustrated.
@austin the code will be interpreted and executed as it is loaded, which is exactly the same with JS. For example, `function foo() { }` is a line of code which, when executed, creates a new global variable called foo and assigns the value of a function body to it. JW is saying this is problematic as it will be done twice.
Rex M
Right -- interpreting and execution both happen when you load a script tag. And remember that many JS files do more than just define functions; some of them call functions as well, or perform other operations.
JW
+1  A: 

Don't output script tags directly in your partials. Create a mechanism to register script files for later inclusion. That mechanism can be responsible for only including files once.

timdev
I like this idea. You could create a helper with a method that could be called like IncludeScript("../js/foo.js"), and have that method keep track of which scripts have already been included for the current request.The only "trick" is storing the data within the scope of the request in order to share information about which scripts have been included between views, templates, and partials. I'm not really sure how to go about doing this in ASP.NET MVC, but I'm sure it's doable and hopefully fairly straightforward
Justin Holzer
To follow up on the previous comment, ASP.NET MVC offers a few options for storing request-scoped data. One option is the ViewData dictionary object, which is available directly as a property to views, partials, templates, or HtmlHelper extension methods. Another option is the Items property of HttpRequest/HttpRequestBase. In both cases, data stored in those collections will be persisted for the life of the request, and available to all views, partials, templates, and HtmlHelper extension methods used during the request.
Justin Holzer
A: 

FF 3.5x, Chrome 4x include it only once.

:) IE 8 has two copies (view in Developer Tools > Scripts tab there are two jquery-1.3.2.min.js entries)

A: 

What happens is that JavaScript is feed into the interpreter the moment it is downloaded. In the event of a namespace collision only the variable name, of a given scope, survives to execution. Normally this last only process prevents problems from arising by overwriting functions feed into the interpreter earlier. The problem is that a function defines variable scope, which those variables could be other functions that introduce then other namespace scopes of variables. That is a problem because if functions share the same name value and include different variable definitions then there could be leakage where variables from a function feed into the interpreter early survive even after that function is overwritten, which can then cause expected namespace collisions.

If the exact same file is included twice there should be no problem. The problem occurs when different versions of the same file are included or different files with the same function names are included. Including the same file twice can mean multiple transmissions, which is a waste of bandwidth.