Getting a faster internet is great - it gives us loads of opportunity to improve the browsing experience through more advanced javascript and designs - I still remember the dreadful websites of the late 90's that took an hour to download and only showed a few random pieces of text on a bright pink (or yellow/ green) background.
Unfortunately not everyone is lucky enough to have the latest technology and with mobile internet becoming more and more popular it's still a very good idea to try to optimise site download time.
Optimising javascript and css is a simple way to speed up the loading of your site. However with more and more frameworks being created and projects growing in scope it's getting harder and harder to manage these things. Nobody wants to optimise a css framework each time it's updated, and invariably these things are made up of multiple files anyway - so I put together a simple script to speed up the download of these files.
Theory
When it comes to css and javascript there are a few things that can affect the download speed - the main factors are...
- The number of files. The more connections that are made to the webserver the slower things download.
- The amount of code (which in turn increases filesize). This is fairly obvious in principle, but people often forget how big css and javascript libraries can be, and optimising them by hand is not feasible.
- The speed of the users internet connection. Something I am always very conscious of. As much as it sucks - not everybody is on broadband, and not everyone with a broadband connection can download things at the same speed you can
Unfortunately number 3 is not something we can change. Yes, connections are getting faster, but that doesn't mean we should use large javascript and css libraries without thinking about visitors who are less fortunate than ourselves.
Solution
The easiest way to reduce the number of files to download would be to copy and paste them all into a single document but that's a pain to update each time you change something. So I developed a simple php script that let's you combine lots of different javascript or css files into one.
The script is below...
<?php
/*
select the content type this script will be serving. This script was
designed for javascript and css files but will no doubt work with other
text files
javascript = text/javascript
css = text/css
*/
$s_contentType = "text/javascript";
/*
file extension for the specified content type
javascript = js
css styles = css
*/
$s_fileType = "js";
/*
base folder to load the files from
this is from the site root so will be something like
http://www.websitename.com/basefolder/
*/
$s_baseFolder = "/scripts/";
/*
use gzip compression or not?
this can also be done on the server side or via htaccess but not all
servers give access to these things so this is a simple workaround. It
may not work or may not be desired so set below as required
*/
$s_useGzip = true;
// -----------------------
// THE BIT THAT DOES STUFF
// -----------------------
$files = $_GET["f"];
$files = addslashes(stripslashes($files));
if($files != null) {
// content type
header("Content-type: " . $s_contentType);
// caching
$offset = 3600 * 24;
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");
header("Cache-Control: max-age=" . $offset);
if($s_useGzip) {
ob_start("ob_gzhandler");
}
// get files
$files = split(",", $_GET["f"]);
// print out the files
foreach($files as $file) {
if($file != "") {
?>
/* [INCLUDE FILE] <?php echo $file; ?> */
<?php
$file = $_SERVER["DOCUMENT_ROOT"] . $s_baseFolder . $file . "." . $s_fileType;
if(file_exists($file)) {
$fileData = readfile($file);
} else {
?>
/* [FILE NOT FOUND] <?php echo $file; ?> */
<?php
}
}
}
if($s_useGzip) {
ob_end_flush();
}
}
?>To make use of the script you would have to set the different properties at the top (content type, file type, base folder and gzip compression). The precautions over file extension and folder location are in place to prevent people from being able to include random files from your site (such as wp-config).
You can then work out your new file url. The filenames should be in a comma separated list without extensions. It should be called something like this...
script.php?f=file1,file2,file3
Because the content type has been set already it can then replace all of the previous scripts (javascript/ css styles) on the site with a single file call.
<-- css file --> <link rel="stylesheet" type="text/css" href="script.php?f=file1,file2,file3" /> <-- javascript file --> <script src="script.php?f=file1,file2,file3" type="text/javascript">
I should point out that I'm not a security expert so if anybody has any ideas for improving the script then please let me know and I'll update accordingly.
8 Responses to “A quick way to speed up your website” Leave a reply ›
Pretty nice idea that, but yeah perhaps security might be an issue, using especially if uses can post code to your website e.g. comments.
The other thing is is using another PHP file to open files rather than the browser including them as the page loads actually quicker? For larger sites I would imagine it in. Also, I was told the other day how 'slow' foreach statements where compared to using while and for loops, and I looked this up and tested it and it doesnt turn out to be true. If you look http://www.phpbench.com/ here, about the third test from the bottom (this is what I tested it with), a for loop is almost 10 times as fast as a foreach, so if you're looking to speed things up this may be something to look at
Another possible way to speed up a site I just tried: CSS Sprites (http://sixrevisions.com/...ve-your-web-page-performance/ number 5). and basically placing all small background images in one larger image and adjusting the background-position accordingly. Great for icons and rollovers, but at the same time on a slow connection it may actually make no difference. 1 large image vs 10 small ones? Also the bandwidth situation with one image being loaded 10 times in this case would be interesting. Don't my limited knowledge of that side of things suffices here!
Bit of an essay, sorry haha, but this post got me thinking
I would be interested to know if this script makes a noticeable difference on lower speed broadband and dial-up connections. Have you had a chance to test out this script on actual low speed connections?
It's a nice idea.
Ben I tested your script over at my site. I setup two pages, one using your script to load the CSS and JavaScript files. The second page was the control group that called all the CSS and JavaScript files individually. Both pages included working example of a jQuery function. I used five javascript files including the jQuery library, and three CSS files. I recorded two numbers from each page load: #1 was the actual amount of time for the page to load, and #2 was the actual amount of time the server took to generate the page. Since the server has to generate the file I felt it appropriate to include the amount of time spent generating the full page. I ran 24 tests of each page. The results follow:
Average Load Time:
Page 1 - Ben's Load Script: 1.80 seconds
Page 2 - Normal Load Method: 1.87 second
Percent of time saved by using the script: 3.84%
Server Page Generation Time:
Page 1 - Ben's Load Script: 1.215069 seconds
Page 2 - Normal Load Method: 1.188876 seconds
Percent of time saved by using the script: (-2.20%)
The above results are from a 1.5Mbps DSL connection.
As soon as I get access to a 56k dial-up modem I will test your script again. I don't want to use a proxy bandwidth limiter for this test, as that isn't an actual test of a 56k modem. I want to make sure all the factors are there including interference as it travels down the line.
Stephen - wow - that's some pretty full on testing you've done. I must admit I haven't actually done any testing myself but I am not sure why my system is so slow. a 3.84% speed up doesn't seem worthwhile. I would expect it to be slower on the first load but future loads should be faster as the content should be cached - did you tests take this into account?
My test was of the cached files. I didn't factor in the first load, but it was a tad bit longer. Thinking back to the network theory stuff, since everything gets broken down into small packets for transmission over the physical medium, the only real savings may be in the form of less file requests, but the actual data sent may be very similar in size, and thus the number of packets sent would be similar in quantity. So on a broadband connection it appears to be relatively close in timing. I may run some tests to verify the number of packets, but right now I am busy finishing up a new flash project, so I wouldn't be able to get around to if for a few weeks.
I still haven't been able to find a landline to use a dial-up connection to test the load script on. I hope someone out there can take the time to run the numbers if they have access to a landline and dial-up connection.
Hi
I may have read your code wrong and please correct me if I have, but...
What I gather is that it GETS from the URL the scripts (CSS and Javascript) that need to be included for the page to work? To me that sounds tricky to maintain, as you would need to mess around with links whenever you want to link to a newly created page or even more annoying if you added another script (then you would need to change all your URLs). I think it would be easier to have a well structured single CSS file for example and organize it that way.
I can understand you trying to speed things up by reducing the number of connections to the web server but I can't see it being practical given the drawbacks mentioned above.
Incidentally a site I created worked something like this below and I never noticed load up differences from much smaller sites. I never tried on 56k though.
Every page had: Include master.php - a single file which included all my other php functions required. This meant that whenever I wanted to add a new function all I had to do was add it into one file and every page would take it onboard as required. Some of the functions were real functions (they just carried out an operation and returned a value), while others actually were for display. For example I wanted to show a particular welcome part on more than one page so I created a function which did this and just included in my master.php - which meant that I could then add this function into any of my web pages and it would understand and oblige normally.
I think the same idea for CSS could be implemented by including a PHP function that includes all your CSS files?
Anyway just another idea for the pot!
Steve
If you are looking to speed up your website you definitely need to try Web Optimizer - http://code.google.com/p/web-optimizator/ . It combines all known and proved techniques and automates overall website speed up process. Fast and simple installation, dozens of settings for complete tuning.
Hi Sunnybear - thanks for the suggestion, it looks like a pretty comprehensive package