views:

3039

answers:

7

I have about 7 Javascript files now (thanks to various jQuery plugins) and 4-5 CSS files. I'm curious as to what's the best practice for dealing with these including where in the document they should be loaded? YSlow tells me that Javascript files should be--where possible--included at the end. The end of the body? It mentions that the delimeter seems to be whether they write content. All my Javascript files are functions and jQuery code (all done when ready()) so that should be OK.

So should I include one CSS and one Javascript file and have those include the rest? Should I concatenate all my files into one? Should I put Javascript my tags at the very end of my document?

Edit: FWIW yes this is PHP.

+2  A: 

You haven't explicitly said that you've got access to a server-side solution, but assuming you do, I've always gone with a method involving using PHP to do the following:

jquery.js.php:

<?php
$jquery = ($_GET['r']) ? explode(',', $_GET['r']) : array('core', 'effects', 'browser', 'cookies', 'center', 'shuffle', 'filestyle', 'metadata');
foreach($jquery as $file)
 {
echo file_get_contents('jquery.' . $file . '.js');
 }
?>

With the snippet above in place, I then call the file just like I normally would:

<script type="text/javascript" src="jquery.js.php"></script>

and then if I'm ever aware of the precise functionality I'm going to need, I just pass in my requirements as a query string (jquery.js.php?r=core,effects). I do the exact same for my CSS requirements if they're ever as branched.

Hexagon Theory
Doesn't this sort of thing inhibit caching?
cletus
If caching's ever a problem when it comes to remote includes, most browsers will kindly reconsider if you just pass a timestamp into the URL...
Hexagon Theory
But... using the caching headers should still be the preferred method.
Allain Lalonde
Don't forget to send the right mime type
alex
+1  A: 

Here's what I do: I use up to two JavaScript files and generally one CSS file for each page. I figure out which JS files will be common across all of my pages (or enough of them so it's close - the file containing jQuery would be a good candidate) and then I concatenate them and minify them using jsmin-php and then I cache the combined file. If there are any JS files left over that are specific to that one page only, I concatenate, minify, and cache them into a single file as well. The first JS file will be called over a number of pages, the second only on that one or maybe a few.

You can use the same concept with CSS if you like with css-min, though I find I usually only use one file for CSS. One thing extra, when I create the cache file, I put in a little PHP code in the beginning of the file to serve it as a GZipped file, which is actually where you'll get most of your savings anyways. You'll also want to set your expiration header so that the user's browser will have a better chance of caching the file as well. I believe you can also enable GZipping through Apache.

For the caching, I check to see if the file creation time is older than the amount of time that I set. If it is, I recreate the cache file and serve it, otherwise I just get the existing cached file.

VirtuosiMedia
Minifying's always good.
Hexagon Theory
+15  A: 

I would suggest using PHP Minify, which lets you create a single HTTP request for a group of JS or CSS files. Minify also handles GZipping, Compression, and HTTP Headers for client side caching.

Edit: Minify will also allow you to setup the request so that for different pages you can include different files. For example a core set of JS files along with custom JS code on certain pages or just the core JS files on other pages.

While in development include all the files as you normally would and then when you get closer to switching to production run minify and join all the CSS and JS files into a single HTTP request. It's really easy to setup and get working with.

Also yes, CSS files should be set in the head, and JS files served at the bottom, since JS files can write to your page and can cause massive time-out issues.

Here's how you should include your JS files:

</div> <!-- Closing Footer Div -->
<script type="application/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.1.min.js"&gt;&lt;/script&gt;
</body>
</html>

Edit: You can also use Cuzillion to see how your page should be set up.

jtyost2
I tried this earlier today and had a couple of issues: firstly my ready() styling came up way later (it was actually quite visible when it was applied), I couldn't embed jquery calls directly in my code (because jquery.js hadn't been loaded yet) and i had some other weird caching issues.
cletus
You don't *have* to put the JavaScript file at the bottom, if you only have one.
VirtuosiMedia
That is correct since the JS files are at the bottom and after the rest of your code has already loaded and run. You may have to recode your site to change this if you still want to bring your YSlow Score up.Personally I haven't had any major issues with it, including using jQuery in my code.
jtyost2
Well for example, I have been using jquery for some custom table styling on several pages. With jquery at the bottom I have to move this to a common file and then make the code work off id or something. just seems a bit wasteful to run that code on every page.
cletus
With minify you can have each page have separate include statements. So for the pages that you need this bit of JS, include it then and don't include it for the other pages. Does that make sense or help?
jtyost2
Hey somewhat unrelated question: on the front page of the Minify site is a listing of bytes sent/received etc for a page. Do you know what that sort of analysis is from?
cletus
Possibly YSlow as well under the components size it will tell you the size of the file and the difference if you have GZipping on makes.
jtyost2
http://stevesouders.com/cuzillion/ Cuzillion will let you play around with how a page should be set up also.
jtyost2
A: 

The idea of minifying and combining the files is great.

I do something similar on my sites but to ease development I suggest some code which looks like this:

if (evironment == production) {
  echo "<style>@import(/Styles/Combined.css);</style>"
} else {
  echo "<style>@import(/Styles/File1.css);</style>"
  echo "<style>@import(/Styles/File2.css);</style>"
}

This should let you keep your files separate during dev for easy management and use the combined file during deployment for quicker page loads. This assumes you have the ability to combine the files and change variables as part of your deploy process.

Definitely look into including your js at the bottom and the css at the top as per YUI recommendations as keeping the JS low has a tangible affect on the appearance of the rest of the page and feels much faster.

marshall
Don't know if the syntax in that post is anything like php. It's just random pseudo code :)
marshall
end the 'echo' lines with ; and add '$' before 'environment' and 'production' for the php version. :)
andyk
A: 

I would not recommend using a javascript based solution (like PHP Minify) to include your css as your page will become unusable if the visitor has javascript disabled.

jeroen
A: 

I also tend to copy+paste all of my jquery plugins into a single file: jquery.plugins.js then link to

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"&gt;

for the actual jquery library.

Birk
+1  A: 

It's probably worth mentioning that I've written tutorials on best practices for this now: Supercharging Javascript in PHP and Supercharging CSS in PHP. These cover the issues of minifying, gzipping and caching.

cletus