Introduction
When we first started building our site with Textpattern, we noticed sluggish page load times that seemed downright unacceptable. After a bit of research and fiddlin’, we finally got out of Textpattern the performance we’re used to seeing on static page managers. The following tips are for the 1.0rc3 version of Textpattern.
1. Turn off logging.
Go to the Admin tab and set Logging to “None” in your Site Preferences. I know it’s convenient to see stats in one place, but there’s better software for tracking those numbers that should have come with your hosting plan. Awstats is a nice one for pretty and details, but we’ve started taking a liking to Shaun Inman’s nimble Shortstat. Unfortunately, Shortstat doesn’t work right out of the box for 1.0rc3.
To make Shortstat fly in Textpattern, change the code in your ‘index.php’ file from this:
<?php
$here = dirname(__FILE__);
include './textpattern/config.php';
include $txpcfg['txpath'].'/publish.php';
textpattern();
?>
to this:
<?php
$here = dirname(__FILE__);
include 'textpattern/config.php';
include $txpcfg['txpath'].'/publish.php';
textpattern();
include_once($_SERVER["DOCUMENT_ROOT"]."/shortstat/inc.stats.php");
?>
Yeah, you just add one line. If you’re using an older version of Textpattern, try Hick’s fix.
If you must have Textpattern’s built-in logging, you could turn off DNS lookup to reduce server processing time. Inside the ‘lib’ folder in your textpattern directory, there’s a nice little file called ‘admin_config.php’. Take a look inside there and set ‘use_dns’ to ‘0’.
2. Turn off/on Send Last-Modified Header.
This is also in your Site Preferences under the Admin tab. Even though this is meant to make pages load faster, I’ve seen reports and anecdotes about things improving / getting worse while having it on / off. Obviously, your mileage will vary.
FYI : We have it on.
Update · There’s an interesting comment on this by Sencer on the Textpattern Forums :
AFAIK the relevant code is commented out in the code base anyway, so you shouldn’ actually see a difference no matter wether you turn it on or off. (publish.php line 163ff., but it’s safe to uncomment it and turn it on) :)
3. Don’t use the built in css editor.
Hate to say it because I think it’s genius, but we noticed a huge decrease in the render time of our pages (you can find it by viewing the source and looking at the bottom of the html) after we made the css file a physical one on the server. It’s not a huge problem to my workflow, because I usually just use View/Edit on my ftp program of choice (Filezilla for pc and Transmit for mac) for quick css editing. If I only have access to a browser there’s always net2ftp or, when I’m desperate, the filebrowser on my cpanel.
4. Turn on gzip compression for php, css and js files.
Using gzip compression was a tip we got from John Hicks. This is actually good for any site, not just Textpattern because it will usually decrease the size of the files served to the user by at least 60%. There are literally over a half a million sites dedicated to doing this one thing. Here’s how we implemented it on our server.
First, we added the following lines to our ‘.htaccess’ file to turn on gzip compression.
php_flag zlib.output_compression On
php_value zlib.output_compression_level 5
Now, all our php files will be compressed before they’re served to the user. To turn on gzip for css and javasript files, we have to make the server think that css and js files are basically php too. To do that, we add the following line to ‘.htaccess’
AddHandler application/x-httpd-php .css .js
The problem is the content-type headers of our css an js files will now look like php application files and won’t be rendered properly in certain browsers like Firefox nor validate on the W3C CSS Validator. To fix this, we created a file called ‘contentHeader.php’ in a folder called ‘includes’with the following code:
<?php
$pathinfo = pathinfo($PHP_SELF);
$extension = $pathinfo['extension']; if($extension == "css"){
header("Content-type: text/css");} if($extension == "js"){
header("Content-type: text/javascript");}
?>
Basically, this little script will look at the extension (.css or .js) and spit out the correct content-type header (text/css or text/javascript). Because we’re not into writing a php include at the top of every javascript and css file we create, we’ll make htaccess do it for us. Just add the following line to ‘.htaccess’:
php_value auto_prepend_file /yourdirectoryto/includes/contentHeader.php
Now our script is included in every php file and will output the proper content-type header based on whether it’s a css or javascript file.
Well, that should do it. If you’ve got additional suggestions for speeding up Textpattern, let us know and we’d be happy to check them out and add them here.
Great article… but why declare a function getExtension that is already built-in in PHP?
The name is pathinfo() and it returns an array: dirname, basename and extension of a given path; built-in functions are faster than declared ones ;)
Ah, good call. Just rewrote the function and it works. I’ll update the code. Thanks Mislav!
$PHP_SELF didn’t work for me.
$_SERVER[‘PHP_SELF’] did however.
Might help some people.
I was excited to see this article, as I was wanting to add Shortstat and speed things up on the site. However, I added the lines to the .htaccess file and my whole site started spitting 500 ErrorMessages. I removed the lines and attempted to upload Shortstat and was promptly told that the server could not find _install.php and when I tried just the shorstat directory it gave me an unknown section (meaning TXP is governing all of my sub-dir???) Anyway, I am a bit confused and if anyone has some pointers I would be much obliged.
What’s in your .htaccess file now? Also, txp should ignore directories that physically exist.
.htaccess has the standard TXP thing:
RewriteEngine On RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^(.+) – [PT,L]
RewriteRule ^(.*) index.php
And I am aware TXP should ignore physical ones, but something is fishy here… and the compression stuff is what was throwing the 500 error. works fine once its removed…
By works fine, I meant the site was up again. I still cant get Shortstat installed…
A couple notes:
1) that’s a cool technique for getting zlib.output_compression to compress CSS and JS files. However, I wonder whether the overhead of the auto_prepend and php parsing of the CSS and JS files is worthwhile for static CSS and JS files, which get cached on the client side anyway.
2) rather than put the zlib compression stuff in the .htaccess file (which may get overwritten with upgrades), I put the following in config.php:
ini_set(‘zlib.output_compression’,’1’); ini_set(‘zlib.output_compression_level’,’5’);
That’ll have the same effect, but there’s less of a risk of overwriting the config.php (in the install it ships as config.php.default to avoid the risk of overwriting the existing config).
It’s also important to note that there are varying levels of compression (1-9, 9 being the highest), but that higher levels of compression may conserve more bandwidth but at a higher processor cost. So really, the question becomes a matter of finding a balance between processor time, bandwidth and transfer speeds. Mileage can vary a lot depending on environmental variables – sometimes compression will actually reduce performance.
Jeremy, that’s a really good point / idea about putting the zlib settings in the config.php file to prevent difficult upgrades, but if you’re like us and always doing crazy things with your .htaccess file, you’ll probably have to maintain it whenever you do something on the server that might manipulate it. Plus, it’s just copy paste.
As far as what might be seen as the negligible difference it makes on compressing css files, I can attest that we saved a pretty good amount on bandwidth when got visited by the slashdot clan. Because the whole css file can fit on fewer tcp packets, it’s a noticeable gain when your browser gets a 2kb file to process as opposed to an 10kb file. Also nice for people who might be doing dynamic things with their css like running php scripts in there. If it’s going to reload each time anyway, might as well be as small as possible.
Just to let you all know, Shortstat is up and running but the additional compression rules for the .htaccess file still throw my site a 500 error message. So I have removed them and will use this at the beginning of my CSS file:
>?php ob_start (“ob_gzhandler”); header(“Content-type: text/css; charset: UTF-8”); header(“Cache-Control: must-revalidate”); $offset = 60 * 60 ; $ExpStr = “Expires: ” . gmdate(“D, d M Y H:i:s”, time() + $offset) . ” GMT”; header($ExpStr); ?
Josh, glad to see you get things flying. Thanks for the update and suggestion.
Will work for me too. Thanks for ideas!
Hi there,
Does the Gzip instructions on this site still work in Textpattern 4.0.1? Thanks for the info.
What a wonderful idea, very nice.
Helo. Ad. 3 Where should i put the css file? I’d put this in root folder, and in Txp folder, and Txp did not find it. (thanks for info abaut gzip, this realy speed up my site;) Thanks
Hi!
I reccomend to use:
php_flag zlib.output_compression 1024
instead of
php_flag zlib.output_compression on
WHY?
Firefox/Mozilla does not work with files less than 1024 bytes.
Everyone needs a hug.
Hi! Very nice site! Thanks you very much! I2d6jcG17c7N
qrxnkt
i guess there is a better and faster way to make it:
create a “cssjs_mime.php” file in your apache conf folder.
in that file add the code:
in your php.ini find the variable auto_prepend_file and add the location to your special mime file just like in the example below:
auto_prepend_file = “c:path_to_apachepath_to_conf_filescssjs_mime.php”