Multiple javascript/css files: best practices? - php

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.

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"></script>
</body>
</html>
Edit: You can also use Cuzillion to see how your page should be set up.

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.

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.

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.

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.

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">
for the actual jquery library.

Related

Prioritizing Critical CSS with PHP during a request

I've read this article, which talks about loading a web page's critical CSS first, and then asynchronously loading other CSS assets once the page has rendered.
Is it possible to use PHP to work out what must be placed in the critical asset file? To my mind, elements like input, textarea, form, table etc, can be loaded later. It's the div, ul, ol, p, hx etc that usually make up the biggest part of the "above the fold" css. Maybe always load these first?
Apart from the most important elements, I'd think the properties that make up the shape of the website are the things that must be loaded first, then the backgrounds and other "paint".
Any good ideas to start with? I'd like to generate and automatically cache the results for website pages automatically and got that all set up. I want to take it a step further with the client-side loading performance, but without too much hassle and extra time during development, while making websites for clients. The framework should do the hard work.
I thought about some smart regexes that would sort it out, but what seems so hard, is the "prioritization"..
Stealing the example from your link. You would put your main styles (div, wrappers, p, images, or any styles for above the fold) in the head to load with the normal way. Once the page loads and runs the script it fires the script to load your css files.
<?php
$cssArray = array('file1.css', 'file2.css', 'file3.css');
?>
<script>
/*!
Modified for brevity from https://github.com/filamentgroup/loadCSS
loadCSS: load a CSS file asynchronously.
[c]2014 #scottjehl, Filament Group, Inc.
Licensed MIT
*/
function loadCSS(href){
var ss = window.document.createElement('link'),
ref = window.document.getElementsByTagName('head')[0];
ss.rel = 'stylesheet';
ss.href = href;
// temporarily, set media to something non-matching to ensure it'll
// fetch without blocking render
ss.media = 'only x';
ref.parentNode.insertBefore(ss, ref);
setTimeout( function(){
// set media back to `all` so that the stylesheet applies once it loads
ss.media = 'all';
},0);
}
<?php
foreach($cssArray as $css) {
print 'loadCss("' . $css . '");'
}
?>
</script>
<noscript>
<!-- Let's not assume anything -->
<?php
foreach($cssArray as $css) {
print '<link rel="stylesheet" href="' . $css . '">'
}
?>
</noscript>
From experience, and best practice, all css calls should be located in your <head> and all script calls should be right before your </body>. All files will load asynchronously to a certain number based on your web server configuration file, normally around 5. Once those files, or one is free, it starts the next file(s)
Automation
This is a whole new host of problems.
Now you will have to load the file and have a set point to stop looking for tags, classes, or id's to check for (using an html parser).
Then you have to load and read your css files to pull out the classes that were found in the previous step.
Output the file to your filesystem in multiple files.
one for first load
others for the javascript method or load at bottom of page
Check the files on creation time, or modified, and remake as needed or call in if they are available
To me this option is two time consuming and can cause problems, and possibly load time decline, if not done properly or you have to process large files. Since most of this work will be done on the server, you wait to get the first byte of data will be longer then just serving them the traditional way.

How do i minify my js in my framework

I have built a customized php framework.
I have a view, controllers and model.
In the view, there is variable which i can set.
$js = array('custom/testimonial.js','jquery.js');
At the footer view i have the following code.
-------------------------------------------------*/
if(isset($js)){
foreach ($js as $jsname) { ?>
<script src="<?php echo MAIN_URL; ?>/resources/js/<?php echo $jsname; ?>"></script>
<?php
}
}
Basically, the code in footer will load all the necessary scripts required for that page. In my other pages, i have other(different) javascripts files to include. This mean thats each page will have different javascript.
I would like to minify the js for each of the page and wonder which is the best way. I tried using Assetic (php asset management) with no luck.
Another question is should i minify javascript on the fly? Means when i load my page called testimonial.php it will check what are the javascript required for the page and minify them before displaying. Will that post performance issues even if i cache it.
I am looking for some methods that has high maintainability as i do not have to minifiy all javascript manually, have 40 to 50 plus pages. (each page uses different javascript files, plugins, lib).
Can Assetic do the job for me? Currently i have problems generating a static file for the javascript.
Appreciated any help.
Yahoo (YUI) used to have a compressor/ minifier, but they're now moving to UglifyJS. See:
https://github.com/yui/yuglify
https://github.com/yui/yuicompressor/
There are also several online minification services, based on the YUI compressor.
http://refresh-sf.com/yui/

Simulate PHP Include Without PHP

I want to include the same navigation menu on multiple pages, however I do not have PHP support, nor can I affect my server in any other way.
I want to avoid simply copying and pasting the html onto all the pages as this would make updating the menu a pain.
The two options I can think of are as follows:
1) Have all the content exist on one page, then determine which content to show based on a keyword appended to the url:
example.com/index?home
example.com/index?news
2) Include a javascript file that has a function that writes the menu out and call the function on each page
function setupMenu() {
$("#nav").html("<ul class='nav'><li>home</li><li>news</li></ul>");
}
With Option 1, the updating process would consist of editing one nav menu on the one page
With Option 2, updating would mean changing the function in the javascript file
My concern with Option 1 is that the page would have to load a lot of content that it wouldn't need to display. My concern for Option 2 may seem trivial but it is that the code can get messy.
Are there any reasons doing it one way would be better than the other? Or is there a third superior option that I'm missing?
You have a few options, each with its own advantages and drawbacks:
Server Side Includes, or SSI. If you don't have PHP there's a good chance you don't have SSI either, and this option requires some irritating mucking-about with your .htaccess file. Check Dominic P.'s answer for a writeup of SSI. The benefit of SSI over JavaScript or Frames is that it doesn't require the user to have JS enabled - which a lot of users don't - and it also doesn't present any navigational difficulties.
Frames. You could either use standard frames to put the navigation in its own separate file, and with the correct styling it would be seamless. You could also use an iframe to place your navigation in an arbitrary part of the site, like a sidebar or whatever. The downside to frames, particularly standard frames, is that they tend to make bookmarking, links and the forward/back buttons behave oddly. On the upside, frames don't need browser compliance or server support.
JavaScript. You can refer to any of the other answers for excellent explanations of the JS solution, particularly if you're using jQuery. However, if your site isn't otherwise dynamic enough that your users will want to have JavaScript enabled, this will mean that a large number of your viewers will not see the menu at all - bad, definitely.
-
Yes use .load jQuery ajax function
$('#result').load('ajax/menu.html');
That way your code stays clean, and you can just edit the includes in seperate HTML files just like PHP.
You should consider AJAX for this task. Include a third party library like jQuery and load the separate HTML files inside placeholders, targeting them by ID.
E.g, in your main HTML page:
<div id="mymenu"></div>
Also, in your main HTML, but in the HEAD section:
$('#mymenu').load('navigation.html');
But your best bet would be to switch to a hosting that supports PHP or any other server-side includes. This will make your life a lot easier.
Check out Server Side Includes. I don't have a whole lot of experience with them, but from what I recall, they are designed to be a solution to just your problem.
Server-side includes: http://www.freewebmasterhelp.com/tutorials/ssi/
You can use HTML Imports http://w3c.github.io/webcomponents/spec/imports/
Here is an example from http://www.html5rocks.com/en/tutorials/webcomponents/imports/
warnings.html contains
<div class="warning">
<style scoped>
h3 {
color: red;
}
</style>
<h3>Warning!</h3>
<p>This page is under construction</p>
</div>
<div class="outdated">
<h3>Heads up!</h3>
<p>This content may be out of date</p>
</div>
Then index.html could contain
<head>
<link rel="import" href="warnings.html">
</head>
<body>
...
<script>
var link = document.querySelector('link[rel="import"]');
var content = link.import;
// Grab DOM from warning.html's document.
var el = content.querySelector('.warning');
document.body.appendChild(el.cloneNode(true));
</script>
</body>

jQuery in CodeIgniter, inside the view or in external js file?

I'm developing web application using CodeIgniter. All this time, I put the custom js code to do fancy stuffs inside the view file. By doing this, I can use site_url() and base_url() function provided by CodeIgniter.
Today I want to separate all custom js code from view file into an external js file. Then it hit me, I cannot use site_url() and base_url() in the external js file. So, I had to move the js code back into view file.
I want to ask opinion, example, and best practice for this kind of problems. Do you put the custom js code inside the view, or in external js file? If you put it in external file, how do you get around the needs for site_url() and base_url() (beside of course put the absolute url that I want to avoid).
I typically keep mine in an external file, but place a single line within my template (view) that declares a javascript variable called "baseurl" that can later be used by my external javascript.
<script type="text/javascript">
var baseurl = "<?php print base_url(); ?>";
</script>
<script type="text/javascript" src="/js/scripts.js"></script>
Now my scripts.js file has access to the base_url() value via its own baseurl variable.
I would do it in a different way - js should be external, obviously, but why not take full advantage of the fact that you have an MVC framework that's perfectly suited to handle all of your javascript magic?
Here's my recipe for Javscript (and CSS) goodness with CI:
Grab a copy of Minify - if you don't know it already, your life will be better. Not in a "Love at first sight / I just discovered jQuery / xkcd / unit testing" kind of way, but at least in a "Dude, prepared statements eradicate SQL injection" kind of way.
Second, create a CI controller that encapsulates Minify (shouldn't be too hard, just remember to set the correct HTTP header and pass the parameters on)
Optionally activate caching to make everything run blazingly fast (Minify has caching built in, but if you're already caching your CI content, you might as well use the same method here.
Optionally define some groups for Minify, to make script loading even nicer
Optionally add the baseurl and siteurl variables (and whatever other values you may need) to the javascript output
And presto, you should now be able to load your scripts by calling the Minify-wrapper:
<script type="text/javascript" src="/min/g=js"></script>
It's crazy fast, it's gzipped, takes just one request rather than many, it gives you full CI control over your scripts, and it even makes your source code cleaner.
Oh, and if you want to be extra nice to your source-code-peeping visitors, you could automatically add something like this to the output:
// Javascript compressed using Minify by Ryan Grove and Steve Clay
// (http://code.google.com/p/minify/)
// Human-readable source files:
// http://www.yourdomain.com/js/core_functions.js
// http://www.yourdomain.com/js/interface.js
// http://www.yourdomain.com/js/newsticker.js
// http://www.yourdomain.com/js/more_magic.js
(...)
At least that's what I do.
Donny, if you start passing through every URL separately you will just be giving yourself a ball-ache. Why not just pass through base_url() and contcat the controller/method on the end?
You lose the ability to swap around index_page and url_suffix settings but they shouldnt really change all that often anyway.

Preventing jQuery from Loading

If jquery is added in globally used header.php across the site then How to stop to load jquery library only for those pages of site which doesn't need actually? If we can't use more than one header.
purpose of question is to not to penalize those page with slow loading which actually don't need.
Your site shouldn't need more than one global-header, if you opt to even use headers to begin with. If it does, just include jQuery on all pages. It's a small cached file, it won't hurt the browsing experience.
By using the google-hosted version, it may be the case that many of your uses already have it cached before they even reach your site.
I have been guilty of pounding my fist into the nail while asking everyone else to move the hammer that's in the way...
Why not tackle the problem from the other end and use jQuery to optimize the first load?
If you have big pages that are already taking a while to download, why not section off the less-performant areas and use $().load() to fill those in?
The page will load quicker (better user experience) and you don't have to be adding any additional processing to pages that don't need it.
Cheers,
-jc
assuming you are loading the jQuery file from a correctly-configured webserver (or from google's CDN), it will be cached and not re-downloaded on each page. Assuming a visitor will hit at least one page on your site that needs jQuery then you really won't gain anything by trying to remove it from loading on pages that don't use any javascript features from the library.
First, use the compressed jquery for production. It's much smaller. Second, IIRC, once jquery is downloaded with the first page, it will be cached and won't need to be retrieved from your server for each subsequent request.
Otherwise, if you really need to explicitly load jquery only on those pages that need it, you would have to have some way for the body of your page to tell header.php that it doesn't need to load jquery. If header.php is loaded before "body.php" then that's pretty hard to do without some fancy output buffering or such.
If you're using a templating system like Smarty you could have a conditional in the master page template to check a $loadjquery flag that you set in body.php before sending the whole page off to be rendered. But that's complicated too.
Your question is very general, some specific would be great, maybe even a link to the site. Personally if you are using a CMS I would try to make some sort of "flag" for that page, or if you are simply loading a page and then loading the header from that page, insert a variable before you load the header and use that as your flag for loading jQuery.
An example:
If a user wants to see www.mysite.com then the following file would be loaded: www.mysite.com/index.php with the following code:
<?php $needJQuery = true;
include('header.php');
echo 'content will go here';
include('footer.php'); ?>
header.php would include something such as this:
<?php if ($needJQuery) { ?>
<script src="/jquery/jquery-min-3.2.1.js" />
etc. for all the content that you need above/below.
<?php } ?>
For the pages that don't need jQuery loaded, you would either leave $needJQuery undefined or you would do as follows:
<?php $needJQuery = false; ?>
Hope this helps,
As stated earlier, modify the header file so it'll check for the presence of flag variable and only output the jquery headers if needed.
If you don't have the ability to modify the header file, you could load it with output buffering turned on and filter the output before it heads out to the client:
<?php
ob_start();
include('header.php');
$header = ob_get_flush();
$cleanheader = some_operation_that_removes_the_jquery_script_tags($header);
echo $cleanheader
?>

Categories