In this article I will discuss how I obtained a 5x speedup on a Smarty driven website on a Lighttpd Web server. This is achieved by enabling Lighttpd to a directly access and serve the cached files directly from the file system, rather than calling into Smarty.
However, even when Smarty is serving up cached pages, there is a lot of overhead added to each request when compared to the Web server directly serving the cached page. This is because PHP is still being loaded, the Smarty library is being included, and a small amount of logic is being performed within Smarty before the cached page is finally being passed along.
In my case, the data changes occur infrequently and a combination of clearing the cache on a scheduled interval plus a method to manually force a recompilation of a specific page is adequate, and a worthwhile trade-off for the performance increase. Also, I am a performance junkie.
This was my lighttpd configuration for the site prior to implementing the cache. It has a few basic rewrite rules so request for a (htm|html) file gets passed to the index.php. This file acts as a handler to determine the actual smarty template to load, enabling the use of friendly URLs.
REXML could not parse this XML/HTML: <pre><code><span style="color: #333333;">$</span></strong>
<strong>server.document-root</strong> = "/var/www/site/html"
<strong>url.rewrite</strong> = (
"/(.*)\.(htm|html)(\?.*)??$" => "/index.php?p=$1",
"/(.*)/(\?.*)??$" => "/index.php?p=$1",
"/(.*)/(.*)/$" => "/index.php?p=$1/$2"
)
}</span></code></pre>
And after implementing the cache, this is the lighttpd host configuration:
REXML could not parse this XML/HTML: <pre><code><span style="color: #333333;"><strong>$</strong>HTTP</span>["host"] =~ "www.site.com" { <strong>server.document-root</strong> = "/var/www/site/html" <strong>magnet.attract-physical-path-to</strong> = ("/var/www/site/html/rewrite.lua") }</span>
Below is the code for rewrite.lua (referenced in the lighttpd conf above) which implements to handle the rewrite rules. It checks the file system to determine if a cached file exists, and if so, it serves that file. Otherwise, it rewrites to the index.php handler so smarty can generate the new cache file.
The cache_path
variable in the rewrite.lua script is my smarty cache dir $smarty->cache_dir
, plus the $smarty->cache_id
(mine is blank, be sure to append it to the cache_path variable as a subdir of your smarty cache_dir)
At this point, lighttpd is rewriting all requests to my index.php handler since it will not find a cached copy in the the cache_path dir. I now have to work with the index.php handler file so Smarty will save the compiled HTML files into the cache_path defined in rewrite.lua. To do this, I wrote a custom cache handler function for smarty and stuck it in the index.php file. So far, my Smarty setup is looking like this:
The main thing here is that the caching is enabled, each request will recompile the template, the compile_id is blank, and the cache_dir matches what is set for cache_path in rewrite.lua.
The function server_rewrite_cache_handler()
overrides the default smarty cache read/write/clear logic so that the file is saved in the correct directory structure that matches the request that was rewritten from lighttpd.
The one last thing is to disable several lines of code in the smarty/internals/core.write_cache_file.php, as by default Smarty will add some serialized data to the top of the cache data it passes to our custom cache handler function. The changes are shown below and occur around line 65 and 66 of the core.write_cache_file.php file.
REXML could not parse this XML/HTML: <pre><code><span style="color: #333333;">#$_cache_info = serialize($smarty->_cache_info); #$params['results'] = strlen($_cache_info) ."\n". $_cache_info.$params['results']; </span></span>
That is all, you should see a drastic speedup at this point.