My app's JavaScript/jQuery is contained in an external scripts.js
file. It generally looks like this:
$('document').on('ready', function() {
giraffe();
elephant();
zebra();
});
function giraffe() {
// code
}
function elephant() {
// code
}
function zebra() {
// code
}
giraffe()
is only used for the view available at /animal/giraffe
elephant()
is only used for the view available at /animal/elephant
zebra()
is only used for the view available at /animal/zebra
,
But all 3 are supposed to run on the view available /animal/all
. This is a rudimentary example, but this is the reasoning behind having them all in one .js
file, apart from keeping HTTP requests to a minimum.
My question is, does this affect the JavaScript rendering? Even though giraffe()
isn't used (has no elements to work on) on /animal/zebra
, it's still being called. Does js/jQuery ignore the function if it finds nothing to do? I'm sure the whole script is read, and that probably takes time. So, what's best way to handle this?
To avoid conflicts, I've created conditionals at the top of the js file to only run the functions that the active page needs:
$('document').on('ready', function() {
var body = $('body');
if( body.hasClass('giraffe') ) {
giraffe();
}
if( body.hasClass('elephant') ) {
elephant();
}
if( body.hasClass('zebra') ) {
zebra();
}
});
This is a little more verbose than I would like, but it is successful in keeping these functions modular/conflict free. I welcome an improvement on this solution.
js can occupy the same file when you deploy your application. To better comprehension and developing, it is good to maintain them into separated files.
The first major benefit of using external CSS style sheets and external JavaScript files is faster load times for your web pages. According to an experiment at Google, even a half a second difference in page load time can make a 20% difference in how much traffic that pages retain.
External JavaScript Advantages Placing scripts in external files has some advantages: It separates HTML and code. It makes HTML and JavaScript easier to read and maintain. Cached JavaScript files can speed up page loads.
To include an external JavaScript file, we can use the script tag with the attribute src . You've already used the src attribute when using images. The value for the src attribute should be the path to your JavaScript file. This script tag should be included between the <head> tags in your HTML document.
It would certainly be better to run just the code you need. It's not that difficult; the only minor complexity is handling your /animals/all
case. If you want to keep all your code in one file, you could do it this way:
var animals = {
giraffe: function() {
console.log( "I'm a giraffe" );
},
elephant: function() {
console.log( "I'm an elephant" );
},
zebra: function() {
console.log( "I'm a zebra" );
}
};
$(function() {
var animal = location.pathname.split('/').pop();
if( animal == 'all' ) {
for( var animal in animals ) {
animals[animal]();
}
}
else if( animal in animals ) {
animals[animal]();
}
else {
console.log( "I'm a mystery animal" );
}
});
You can actually test this code by going to URLs like this right here on Stack Overflow, and then pasting that code into the JavaScript console:
https://stackoverflow.com/animal/giraffe
https://stackoverflow.com/animal/elephant
https://stackoverflow.com/animal/zebra
https://stackoverflow.com/animal/ocelot
https://stackoverflow.com/animal/all
Update: OK, so you explained in the comment that the actual situation is a bit more complicated. I'll leave this code here in case it's useful for anyone, but for your situation you may be closer to what you need with the code you already have.
WRT the question of what one of your animal functions will do when you're on a page it doesn't relate to, of course that depends on how it's coded. It may successfully do nothing, or it may have an error, right?
Since we're talking about jQuery code, here are a couple of examples. Suppose you have code that's looking for an element by ID and then assumes that the element exists:
var zebraElement = $('#zebra')[0];
console.log( zebraElement.value );
On a page where the #zebra
element exists, this code will log its value
attribute. (I'm assuming for discussion that it's an element that has a value, such as an input element.)
But if #zebra
is not present, then zebraElement
is undefined
, and attemping to access its value
will fail and land in the debugger.
OTOH, if you coded that like this:
var $zebra = $('#zebra');
console.log( $zebra.val() );
it wouldn't fail if #zebra
is missing, it would successfully print undefined
without causing an error.
Similarly, if you have code that uses $().each()
, it will typically run without failure when the element(s) are missing, because it simply won't execute the callback function:
$('.animal').each( function( i, e ) {
console.log( $(e).val() );
});
If there are no elements with class="animal"
, then the console.log()
call will never be reached. So there's no error, it just doesn't do anything.
Depending on what you're doing, this can be a perfectly reasonable way to fire up only the behavior you need—simply make sure your code handles the missing DOM elements by cleanly doing nothing.
Also be sure to read nick's answer for more insights.
And one more update… In the comment you mentioned keying off classnames on the body
element. A nice way to do that would be similar to the code example above. You don't need a conditional for each animal, just a loop and a single conditional:
var animals = {
giraffe: function() {
console.log( "I'm a giraffe" );
},
elephant: function() {
console.log( "I'm an elephant" );
},
zebra: function() {
console.log( "I'm a zebra" );
}
};
$(function() {
var $body = $('body');
for( var animal in animals ) {
if( $body.hasClass(animal) ) {
animals[animal]();
}
}
});
So, for example, if you have <body class="giraffe zebra">
it will call the animals.giraffe()
and animals.zebra()
functions.
There are actually two issues here, one is whether to load all the functions and the other is whether to run them all. The question about whether to run them all (and some solutions to running just the functions you need) has been well addressed by Michael Geary in the other answers.
So, should you load them all? You need to weigh up the time needed to download a larger file over making extra http requests. With only three 'groups' of functions shared between 3 pages (and one page using all of them) and when you expect the user to be changing pages regularly I would go with one file.
Once your project gets very big you'll want to use something like requirejs to manage your scripts and load them asynchronously. Loading your js scripts asynchronously will increase the speed of the page (and the perceived speed of the page) and if there are issues (especially with scripts hosted by third-parties) your page wont get help up. You can of course do this without a library:
With HTML5:
<script async src="http://google.com/script.js"></script>
There are a million ways to load asynchronously with pure JS, one way:
<script>
var resource = document.createElement('script');
resource.src = "//google.com/script.js";
var script = document.getElementsByTagName('script')[0];
script.parentNode.insertBefore(resource, script);
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With