As we have just finished discussing in our previous article (How to add and Test GZip Compression on your Website's Web Pages - linked above), adding GZip to your Website using php-cgi can be an awkward subject to piece together from snippets about the 'net. And so for those that have found difficulty with this subject, we decided to present a relatively easy "show me how" guide to step those in need of an alternative technique which would allow them to successfully zip their .html pages and the external .css on the fly.
These articles are geared for PHP CGI use with Apache. I can tell you that on a local system, this method works with any type of PHP installation (module or cgi).
Some of you, those more serious about learning what goes on between browser and server, downloaded the linked FireBug and Page-Speed programs which runs with FireFox. When you load your page in FireFox, you would then click the "bug" icon (bottom right corner), then PageSpeed. This gives your page a score out of 100. Nice. But what we want is the Resources tab information. Click this and locate your HTML file in the list and check the Transfer Size column which should now be smaller than File Size column. However, you will note that your .css may be compressed, but for some reason, has failed to render the data in your html.
This is almost as simple as GZipping our .HTML files. But we are most likely to run into header problems which is why we thought we should expand your education on this subject.
In our first article, we learned how the visitor would call your test.html file which doesn't exist on your server. However, using Apache's rewrite module, apache decided to process a file named test.php instead, which was just a normal .html file that we renamed with a .php extension. Php didn't care if there was any php code inside the file or not, it just faithfully zipped the file and let Apache send it back to the visitor as test.html in a compressed gzip format. And everybody was happy and toasting to honours in your name.
Well, this flow chart is right enough, and so it follows we just need to add css next to html in our rewrite command in .htaccess. Then we would have gzipped .css files! Easy Peasy Lemon Squeezy!
Alas, if only it were that simple...
If we simply add .css to our .htaccess code like so,
RewriteRule ^(.+)\.(html|htm|css)$ $1.php [L]
which works perfectly for .html and .htm but as far as .css goes, we almost get there. And almost is not a good enough result. Though the css is now gzipped, your page has failed to render the external .css data. (Oh, and you thought it didn't work at all).
If you upload the amended ,htaccess code, reload your page (which fails to render the .css) and re-initialize your FireBug/Page-Speed resources screen, you will note that your .css code is now gzipped, but not where it counts. The difference lays between the Request Headers and the Response Headers. More specifically, it is the Response Header's Content Type.
We need it to state:
And so to fix it, we first make sure our house (directory structure) is in good order and then apply a solution to fix this issue.
If your website already uses a separate css folder, great, jump to the next heading.
If you took our last article to heart, and are now serving all .html files gzipped, then all your.html files on your site are now renamed to .php. And the only place you need your html2php2html apache rewrite code is in your web root .htaccess file. No matter what sub-directory the visitor calls for an .html file from, .htaccess will sort it out for you and give the visitor what they want. You can have the command in other .htaccess files in other subdirectories too, though in most cases, it will be a waste of your server's time. .htaccess will work on every deeper subdirectory unless it meets another .htaccess file which alters the original content. And because our .css file will also be a .php file we are going to add a twist, so let's make sure we can easily target our .css files first.
Just as you would have a different sub-directory for images and another for thumbs (thumbnail images) you should have a separate directory for .css files and another for .js files. You should have learnt this in any Website Directory Structure 101 Course. If you have not set up your website with a separate folder/directory for css files, you should do this now and amend all your html (php) files so that they point to the correct path to load the css file. (If you want to gzip .js files etc., you should do the same for those file types too)
We want a special folder for our CSS files because our appended php script will set the response header for our css that will correctly render the html file in the visitor's browser. It will be a different php script that will take care of this and we want to keep the process as simple as can be and away from other php files that don't need that header.
So, in this example, We rename our external .css file as testcss.php. We have also renamed our test.html file as test.php and we correct the data in the HTML HEAD code like so to point to a .css file in a subdirectory labeled css:
<link rel="stylesheet" href="css/testcss.css" type="text/css" media="all" title="all" charset="utf-8" />
This may seem odd, but apache and php will work out the differences between the .css and .php extentions. With this method, all your pages are still written and appear as .css and .html to the visitor. When finished, you will call your test.html and that will call /css/testcss.css. That will be the apparency. We use the test directory so we don't disrupt your site during testing.
In the previous article, we created a test directory (your_www_root/test/) which contained:
a) your newly created test.html file that you have renamed as test.php,
b) your newly created php.ini file and
c) your newly created .new htaccess file
d) your newly created mygzip.php
To contine testing with that setup, we will now create another subdirectory inside that test directory for our .css file which is to be renamed as a .php file. This new sub-directory enables us to process the HTML and CSS files separately. This is needed as they require a different response header.
Our new sub-directory can have the name of css (your_www_root/test/css/) and will contain the following files:
a) your newly created testcss.css file that you have renamed as testcss.php,
b) your newly created php.ini file and
c) your newly created mygzip_css.php
d) note: it is best to edit the .htaccess file in the test directory with the new changes. This is how it is done professionally.
This time we make use of PHP's "prepend" command to also add our needed header data so that the visitor's browser will understand we are sending the css data. This example shows UTF-8 as the charset but you can choose ISO-8859-1 etc.
This is not the same file we would use for our html2php.
Using a text editor like notepad, copy and save this next piece of code as a separate file. Eg. as mygzip_css.php and upload it to your Web Site. (eg: www.SomeWebSite.com/test/css/mygzip_css.php)
if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler");
This step is complete when you have uploaded this new file (mygzip_css.php) to a permanent directory. Our php.ini for our css data will point to this file. (Note: You can also just copy and paste the above code at the very beginning of all your (.css) .php files if you do not want to add the "prepend" file step. And again, you would also skip the php.ini step in this scenario and go straight to the .htaccess step.)
Again, we make a php.ini file unless one already exists in the CSS directory, in which case we would add to it. Remember to rename your .css files to .php files. (note: One server I was working on changed the file permissions of files I renamed from .css to .php from 644 to 600. This returned a permission error. I resolved this problem by using FileZilla's right click menu "file permissions" and changing the file back to 644).
We just add one line of code to our php.ini (note: file=/full server path/DirectoryPath/mygzip_css.php) See our first gzip article if you are not sure what your full server path is. You do not just copy and paste this code, you need to edit it to suit your website.)
This step is complete when you have uploaded your new file (php.ini) to the directory which has the .php (.css) files we want to gzip.
Our final step is to create a new .htaccess file for the CSS inclusion (or add to it if one already exists). It is very important to have the correct php.ini file in the correct sub directory
This next piece of code tells apache to treat an incoming request for the .css file(s) as a request for a .php file. PHP can then "prepend" our ob_gzhandler script which also has our ammended header code. Apache then returns the handled data back to the originator as .css. Upload this next .htaccess code snippet to your css folder. However, if you now have all your css and html in separate folders / directories and renamed as php files,.then you really only need the one htaccess file in your web root directory and let apache sort 'em out. Replace the code we used in our first lesson with this one:
# Configures HTML2PHP2HTML handling (php.ini is in html folder points to mygzip.php).
# Configures CSS2PHP2CSS handling (php.ini in the css folder points to mygzip_css.php).
RewriteRule ^(.+)\.(html|htm|css)$ $1.php [L]
You are now ready to test it all out.
This is what happens now on our server:
User requests test.html which also calls testcss.css
Apache doesn't bother to look for test.html but looks for and processes our test.php and testcss.php instead
Php checks if GZip result required then processes test.php and testcss.php accordingly
Apache returns output to user as test.html and testcss.css
You should now be able to work out how to GZip your .js files too or any other file type that you think would need gzipping.
That's it. You are now able to serve pages compressed with GZip. You can test GZip compression for any Web Page with these resources below. Check yours, check mine or check another's.
And now we have made our .html and .css speed efficient, we can take a look at what else creates a glut in transferring data to our visitors. Mmmm, ever noticed how some of those third party ads can really add to the file size of your webpage. If you could get some control over what you advertize, perhaps you could speed up your site even more and have a chance at making a bigger return for providing leads. Take a review of our article on affiliate websites or visit shareasale.com and you will find some products that will go nicely with your site.
First article in this series: GZipping HTML Files
Article Authored by: Steve Campisi