FCGI::Buffer - Vérifier, mettre en cache et optimiser la sortie FCGI
Version 0.19
FCGI::Buffer vérifie le code HTML que vous produisez en le transmettant via HTML::Lint
.
FCGI::Buffer optimise les programmes FCGI en réduisant, filtrant et compressant la sortie pour accélérer la transmission et en utilisant de manière presque transparente les caches client et serveur.
Pour exploiter les caches clients, c'est-à-dire réduire les appels inutiles vers votre serveur demandant les mêmes données :
use FCGI;
use FCGI::Buffer;
# ...
my $request = FCGI::Request();
while($request->FCGI::Accept() >= 0) {
my $buffer = FCGI::Buffer->new();
$buffer->init(
optimise_content => 1,
lint_content => 0,
);
# ...
}
Pour utiliser également les caches du serveur, c'est-à-dire pour sauvegarder la sortie régénérée lorsque différents clients vous demandent les mêmes données, vous devrez créer un cache. Mais c'est simple :
use FCGI;
use CHI;
use FCGI::Buffer;
# ...
my $request = FCGI::Request();
while($request->FCGI::Accept() >= 0) {
my $buffer = FCGI::Buffer->new();
$buffer->init(
optimise_content => 1,
lint_content => 0,
cache => CHI->new(driver => 'File')
);
if($buffer->is_cached()) {
# Nothing has changed - use the version in the cache
$request->Finish();
next;
# ...
}
}
Pour empêcher temporairement l'utilisation de caches côté serveur, par exemple lors du débogage avant de publier une modification de code, définissez la variable d'environnement NO_CACHE sur n'importe quelle valeur non nulle. Cela empêchera également l'ajout d'ETag à l'en-tête. Si vous obtenez des erreurs concernant les caractères larges lors de l'impression, cela signifie que vous avez oublié d'émettre du HTML pur sur les caractères non-ASCII. Voir HTML :: Entités. En guise de solution de piratage, vous pouvez également supprimer les accents, etc. en utilisant Text::Unidecode, qui fonctionne bien mais n'est pas vraiment ce que vous voulez.
Créez un objet FCGI::Buffer. Faites-en une pour chaque FCGI::Accept.
Définissez diverses options et remplacez les valeurs par défaut.
# Put this toward the top of your program before you do anything
# By default, generate_tag, generate_304 and compress_content are ON,
# optimise_content and lint_content are OFF. Set optimise_content to 2 to
# do aggressive JavaScript optimisations which may fail.
use FCGI::Buffer;
my $buffer = FCGI::Buffer->new()->init({
generate_etag => 1, # make good use of client's cache
generate_last_modified => 1, # more use of client's cache
compress_content => 1, # if gzip the output
optimise_content => 0, # optimise your program's HTML, CSS and JavaScript
cache => CHI->new(driver => 'File'), # cache requests
cache_key => 'string', # key for the cache
cache_age => '10 minutes', # how long to store responses in the cache
logger => $self->{logger},
lint_content => 0, # Pass through HTML::Lint
generate_304 => 1, # When appropriate, generate 304: Not modified
save_to => { directory => '/var/www/htdocs/save_to', ttl => 600, create_table => 1 },
info => CGI::Info->new(),
lingua => CGI::Lingua->new(),
});
Si aucune clé de cache n'est donnée, une clé sera générée et elle ne sera peut-être pas unique. Le cache_key doit être une valeur unique dépendant des valeurs définies par le navigateur.
L'objet cache sera un objet qui comprend les messages get_object(), set(), remove() et create_at(), comme un objet CHI. Il est utilisé comme cache côté serveur pour réduire le besoin de réexécuter les accès à la base de données.
Les éléments restent par défaut dans le cache côté serveur pendant 10 minutes. Cela peut être remplacé par l'en-tête HTTP cache_control dans la requête, et la valeur par défaut peut être modifiée par l'argument cache_age en init().
Save_to est une fonctionnalité qui stocke la sortie des pages dynamiques dans votre arborescence htdocs et remplace les futurs liens pointant vers cette page par des liens statiques pour éviter de passer par CGI. Ttl est défini sur le nombre de secondes pendant lesquelles les pages statiques sont considérées comme étant actives, la valeur par défaut est de 10 minutes. Si la valeur est 0, la page est active pour toujours. Pour activer save_to, une information et des arguments lingua doivent également être fournis. Cela fonctionne mieux lorsque le cache est également fourni. À utiliser uniquement lorsque la sortie est garantie d'être la même avec un ensemble d'arguments donné (les mêmes critères pour activer generate_304). Vous pouvez le désactiver au cas par cas ainsi :
my $params = CGI::Info->new()->params();
if($params->{'send_private_email'}) {
$buffer->init('save_to' => undef);
}
Info est un argument facultatif pour donner des informations sur l'environnement FCGI, par exemple un objet CGI::Info.
Logger sera un objet qui comprend debug() tel qu'un objet Log::Log4perl.
Pour générer un en-tête last_modified, vous devez donner un objet cache.
Init permet de transmettre une référence des options. Donc les deux fonctionnent : utilisez FCGI::Buffer ; #... mon $buffer = FCGI::Buffer->new(); $b->init(generate_etag => 1); $b->init({ generate_etag => 1, info => CGI::Info->new() });
De manière générale, il est préférable de passer par référence car cela copie moins sur la pile.
Si vous donnez un cache à init() puis donnez plus tard cache => undef, le cache côté serveur n'est plus utilisé. Ceci est utile lorsque vous trouvez une condition d'erreur lors de la création de votre code HTML et décidez que vous ne souhaitez plus stocker la sortie dans le cache.
Synonyme d'init, conservé pour des raisons historiques.
Renvoie vrai si le serveur est autorisé à stocker les résultats localement. Il s'agit de la valeur de X-Cache dans l'en-tête renvoyé.
Renvoie vrai si la sortie est mise en cache. Si tel est le cas, cela signifie que toutes les routines coûteuses du script FCGI peuvent être contournées car le résultat est déjà stocké dans le cache.
# Put this toward the top of your program before you do anything
# Example key generation - use whatever you want as something
# unique for this call, so that subsequent calls with the same
# values match something in the cache
use CGI::Info;
use CGI::Lingua;
use FCGI::Buffer;
my $i = CGI::Info->new();
my $l = CGI::Lingua->new(supported => ['en']);
# To use server side caching you must give the cache argument, however
# the cache_key argument is optional - if you don't give one then one will
# be generated for you
my $buffer = FCGI::Buffer->new();
if($buffer->can_cache()) {
$buffer->init(
cache => CHI->new(driver => 'File'),
cache_key => $i->domain_name() . '/' . $i->script_name() . '/' . $i->as_string() . '/' . $l->language()
);
if($buffer->is_cached()) {
# Output will be retrieved from the cache and sent automatically
exit;
}
}
# Not in the cache, so now do our expensive computing to generate the
# results
print "Content-type: text/htmln";
# ...
Nigel Horne,
FCGI::Buffer devrait être sûr même dans les scripts qui produisent de nombreux résultats différents, par exemple dans les situations de commerce électronique. Cependant, sur de telles pages, je vous conseille fortement de définir generate_304 sur 0 et d'envoyer l'en-tête HTTP "Cache-Control: no-cache".
Lorsque vous utilisez un modèle, assurez-vous de ne pas l'utiliser pour sortir sur STDOUT, vous devrez plutôt le capturer dans une variable et l'imprimer. Par exemple:
my $output;
$template->process($input, $vars, $output) || ($output = $template->error());
print $output;
Peut produire du JavaScript bogué si vous utilisez la technique