Tony Landis home

How I sped up Smarty by 5x on Lighttpd

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.

Why is this approach so much faster?

Smarty’s caching engine does a great job at compiling the templates at the correct interval and this creates a drastic speedup compared to recompiling the template on each page request.

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.

Is this caching technique right for every situation?

In cases where the cache life must be very short due to frequent changes to the data being rendered, the approach I will explain in this article may not be viable. However, in these cases it would be still possible to use a push method to remove cache when the data changes, versus adding the overhead of checking for changes on each page request. In my opinion, this push approach to caching reduces the cost to the lowest possible value, so if the need for performance is of the utmost importance, then it makes sense to implement this approach.

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.

Implementation Notes

Since Smarty is a flexible library, every implementation is unique. So while I cannot give imperitive instructions on how you can implement this lighttpd cache, can explain how I did it.

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)(\?.*)??$" =&gt; "/index.php?p=$1",
    "/(.*)/(\?.*)??$" =&gt; "/index.php?p=$1",
        "/(.*)/(.*)/$" =&gt; "/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)


              
cache_path = "/var/www/site/tmp"

              
cache_code = "compile"

              


              
-- render and cache to the filesystem

              
function cache_gen()

              
lighty.env["physical.path"] = lighty.env["physical.doc-root"] .. "/index.php"

              
lighty.env["uri.query"] = "p=" .. string.gsub(lighty.env["uri.path"], "\.(htm|html)$", "")

              
--print ("CACHE: " .. lighty.env["uri.query"])

              
end

              


              
-- load the cached copy from the filesystem

              
function cache_load()

              
lighty.env["physical.path"] = cache_path .. lighty.env["uri.path"]

              
--print ("LOAD: " .. cache_path .. lighty.env["uri.path"])

              
end

              


              
-- add index file if directory listing requested

              
if(lighty.env["uri.path"] == "" or string.find(lighty.env["uri.path"], "/", -1)) then

              
lighty.env["uri.path"] = lighty.env["uri.path"] .. "index.html"

              
end

              


              
-- process htm|html file requests

              
if(string.find(lighty.env["uri.path"], "htm", -4)) then

              
exists = lighty.stat(cache_path .. lighty.env["uri.path"])

              


              
cache_code_passed = false

              
if(lighty.env["uri.query"] ) then

              
cache_code_passed = string.find(lighty.env["uri.query"], cache_code)

              
end

              


              
if(exists and not cache_code_passed) then

              
action = cache_load()

              
else

              
action = cache_gen()

              
end

              
end

            
brought to you by .

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:


              
<?php

              


              
require "../includes/smarty/Smarty.class.php";

              
$smarty = new Smarty;

              
$smarty->template_dir = 'templates';

              
$smarty->compile_dir = 'compile';

              


              
$smarty->cache_dir = '/var/www/site/tmp';

              
$smarty->caching = true;

              
$smarty->force_compile = true;

              
$smarty->compile_id = '';

              


              
$smarty->cache_handler_func = 'server_rewrite_cache_handler';

              
function server_rewrite_cache_handler($action, &$smarty_obj, &$cache_content, $tpl_file=null, $cache_id=null, $compile_id=null, $exp_time=null)

              
{

              
$cache_file = $smarty_obj->cache_dir . '/' . $compile_id . $cache_id;

              
if(!is_file($cache_file)) {

              
$base_file = basename($cache_file);

              
$base_dir = dirname($cache_file);

              
if(!is_dir($base_dir)) mkdir($base_dir, 0777, true);

              
}

              
    switch ($action) {

              
        case 'read':

              
         if(!is_file($cache_file)) return false; else return true;

              
            break;

              
        case 'write':

              
         return file_put_contents($cache_file, $cache_content);

              
            break;

              
        case 'clear':

              
         return @unlink($cache_file);

              
            break;

              
        default:

              
            return false;

              
            break;

              
    }

              
}

              


              
$_p = $_REQUEST['p']; // detect the actual file path requested so I can save the cached copy with the correct path and filename

              
$page = ''; // my logic here to determine the correct smarty template to display

              
$smarty->display($page, $_p);

              


              
?>

            
brought to you by .

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-&gt;_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.

купить диплом техникума купить аттестат за 11 класс купить диплом техникума купить диплом университета купить диплом http://diplomy-originaly.com купить диплом фармацевта где купить диплом купить диплом нового образца купить диплом колледжа купить диплом о среднем образовании http://diplomsagroups.com купить диплом фармацевта купить диплом фармацевта https://gosznac-diploma.com/ купить диплом специалиста купить диплом фармацевта купить диплом с регистрацией купить диплом с занесением в реестр купить диплом в москве где купить диплом купить диплом техникума с занесением в реестр купить диплом о высшем образовании https://russian-diplom.com купить диплом с занесением в реестр реально купить диплом специалиста http://rudiplomirovanie.com купить диплом с занесен ем в реестр купить диплом института http://aurus-diploms.com купить диплом с реестром цена купить аттестат за 11 класс https://premiums-diploms.com купить диплом с занесением в реестр реально купить диплом автомеханика http://russdiplomiki.com купить диплом с реестром купить диплом автомеханика https://diplomansy.com купить диплом без реестра купить диплом о среднем образовании https://diploms-asx.com купить диплом с занесением в реестр цена купить диплом в москве https://diploms-asx.com купить диплом с занесением в реестр купить диплом фармацевта https://eonline-diploms.com купить настоящий диплом реестр купить диплом института купить диплом института купить диплом с реестром купить дипломы о высшем http://diplomrussian.com купить диплом с проводкой купить диплом университета купить диплом института купить диплом с занесением в реестр купить диплом о среднем специальном купить диплом в москве купить диплом техникума с занесением в реестр купить диплом института https://russiany-diploman.com/ купить диплом с занесением в реестр цена купить диплом кандидата наук купить диплом университета купить диплом техникума с занесением в реестр купить диплом врача https://rudiplomisty24.com/ купить диплом с реестром цена москва купить диплом фармацевта https://land-diplom.com/ купить диплом пту с занесением в реестр купить свидетельство о браке купить аттестат купить диплом с занесением в реестр купить аттестат за 11 класс https://diplomsy-landsy24.ru/ купить диплом высшем образовании занесением реестр купить диплом врача купить аттестат за 9 класс куплю диплом техникума реестр купить диплом института купить диплом о высшем образовании купить диплом с реестром цена купить диплом фармацевта купить диплом фармацевта купить медицинский диплом с занесением в реестр купить диплом о высшем образовании купить свидетельство о браке купить диплом с реестром цена купить диплом о высшем образовании http://aurus-diploms.com/kupit-diplom-farmacevta.html купить диплом с занесен ем в реестр купить диплом о среднем специальном купить диплом вуза с реестром купить диплом колледжа с занесением в реестр купить диплом автомеханика http://diploms-service.com/diplomy-po-gorodam/ufa купить диплом с реестром купить диплом о среднем образовании https://diploms-asx.com/ купить диплом техникума с занесением в реестр купить аттестат за 9 классhttps://russdiplomiki.com/kupit-diplom-v-ekaterinburge.html купить диплом врача с занесением в реестр купить диплом кандидата наук купить диплом училища где купить диплом с реестром купить свидетельство о браке купить диплом специалиста купить диплом с занесен ем в реестр купить диплом о высшем образовании https://ukrdiplom.com куплю диплом техникума реестр купить диплом врача купить диплом для иностранцев купить диплом с реестром цена москва купить аттестат за 11 классаттестат купить купить диплом медсестры с занесением в реестр купить диплом ссср https://diploms-goznak.com купить диплом с занесением в реестр цена
купить диплом техникума
https://aurus-diplomany.com
купить диплом магистра
купить аттестат за 11 класс
https://russiany-diplomana.com
купить диплом ссср
купить диплом о высшем образовании
купить диплом фармацевта
купить диплом о среднем специальном
купить диплом техникума
https://premialnie-diplomas.com
купить диплом магистра
купить свидетельство о рождении
купить диплом бакалавра
купить диплом кандидата наук