Compression classique via htaccess
Placé à la racine du site internet, le fichier htaccess permet d'éditer des paramètres de configuration. Dans le cas de la compression, les commandes suivantes permettent d'activer la compression des ressources et de fixer la date d'expiration des fichiers.SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/x-javascript
<FilesMatch ".(ico|gif|jpg|jpeg|png)$">
Header set Cache-Control "max-age=29030400"
</FilesMatch>
<FilesMatch ".(js|css|pdf|txt|swf)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
Ce paramétrage n'est pas toujours accessible sur les hébergements mutualisés et notamment sur 1and1.fr.
Compression gzip sur 1and1
Après de nombreux essais avec htaccess, j'ai abandonné cette solution qui semble impossible.Une alternative au module mod_gzip via htaccess est la compression à la volée avec ob_start() et ob_end_flush(). Le principe consiste à ouvrir le fichier js ou css avec PHP puis de compresser le buffer de sortie.
A nouveau les tests sur l'hébergement 1and1 n'ont pas été concluants !
Pour mettre en place la compression des fichiers css et js, nous allons suivre une autre méthode:
- compression gzip des fichiers avec gzencode(),
- configuration du header en fixant une date d'expiration,
- mise en cache des fichiers.
<?php
/**
* Compresser les fichiers css et les fichiers js sur 1and1
* @author Fobec.com 02/04/2012
* @copyright http://www.fobec.com/tuto/1114/compression-gzip-fichiers-css-javascript-chez-1and1.html
*/
//Constante
$SITE_PATH='/kunden/homepages/40/d00000000/htdocs/';
$CACHE_PATH='/kunden/homepages/40/d00000000/htdocs/cache/';
/*******************************************************************************
* le fichier css ou js n'existe pas sur le serveur
* @return rien
******************************************************************************/
$file=$SITE_PATH.$_GET['f'];
if (!isset($_GET['f']) || !file_exists($file)) {
exit(0);
}
$name=basename($file);
$file_cache=$CACHE_PATH.'res/'.$name.'.gz';
$file_ext=strtolower(strrchr($_GET['f'],'.'));
/*******************************************************************************
* Déterminer le type de ressource
******************************************************************************/
$header_contenttype = 'text/plain';
if ($file_ext=='.css') {
$header_contenttype = 'text/css';
} else if ($file_ext=='.js') {
$header_contenttype = 'text/javascript';
} else {
//pas de css ou js
exit(0);
}
/*****************************************************************************
* Charger le contenu fichier css ou js
*****************************************************************************/
$buf=file_get_contents($file);
/*******************************************************************************
* La requete porte sur un fichier non compressé
******************************************************************************/
if (stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')=== false) {
$len=strlen($buf);
header("Content-type: $header_contenttype; charset: UTF-8");
header('Content-Length: '.$len);
header('Vary: Accept-Encoding');
header('Expires: '.gmdate('D, d M Y H:i:s GMT', strtotime(" 1 month")));
echo $buf;
exit(0);
}
/*******************************************************************************
* La requete porte sur un fichier compressé
******************************************************************************/
//Rechercher la ressource en cache
$filedt=filemtime($file);
if (file_exists($file_cache)) {
$file_cachedt=filemtime($file_cache);
} else {
$file_cachedt=0;
}
//Compression du buffer ou lecture du cache
if ($file_cachedt>$filedt) {
$gz=file_get_contents($file_cache);
} else {
//compression
$gz = gzencode($buf, 6);
//ecriture cache
$fhandle=fopen($file_cache, 'w');
if ($fhandle) {
fwrite($fhandle, $gz);
fclose($fhandle);
}
$file_cachedt=filemtime($file_cache);
}
/*******************************************************************************
* Envoyer la ressource compressé au navigateur
******************************************************************************/
$len=strlen($gz);
header("Content-type: $header_contenttype; charset: UTF-8");
header('Content-Length: '.$len);
header('Content-Encoding: gzip');
header('Vary: Accept-Encoding');
header('Expires: '.gmdate('D, d M Y H:i:s GMT', strtotime(" 1 month")));
header('Last-Modified: '.gmdate('D, d M Y H:i:s GMT', $file_cachedt));
echo $gz;
?>
Mise en place sur un hébergement mutualisé 1and1
Script gzipEnregistrez le script ci-dessous à la racine du site web. Nommez le fichier par exemple gzip.php
Nouveau répertoire
Avec un logiciel FTP, créez un dossier 'cache/' à la racine du site web.
Page HTML
Les liens vers les feuilles de style et les fichier js sont déclarés dans les pages HTML. Modifiez les balises meta ainsi:
Feuille de style:
<link type="text/css" rel="stylesheet" href="http://www.monsite.com/res/file.css"/>
est remplacé par
<link type="text/css" rel="stylesheet" href="http://www.monsite.com/gzip.php?f=res/file.css"/>
Fichier javascript
<script type="text/javascript" src="http://www.monsite.com/res/folib.js"></script>
est remplacé par
<script type="text/javascript" src="http://www.monsite.com/gzip.php?f=res/folib.js"></script>
Tests de la compression Gzip
Lorsque le script gzip.php et la configuration des fichiers HTML sont en place, vérifions que tout fonctionne comme prévu:
- tester la réponse du serveur avec http://web-sniffer.net/, tantôt en demandant un ressource compressée, tantôt en demandant une ressource non compressée.
- vérifier la création du fichier cache. Dans le dossier '/cache/' du site internet, 2 types de fichiers doivent s'y trouver, les feuilles de style par exemple file.css.gz et les ressources javascript file.js.gz.
Amélioration du script de compression
Regrouper les fichiers à compresserLorsqu'une page HTML comporte plusieurs feuilles de style ou plusieurs fichiers js, l'idéal est de regrouper le tout en un seul fichier. La vitesse de chargement en sera grandement améliorée. A partir du script gzip.php, le regroupement des fichiers est assez simple à faire.
Minifier les fichiers
Les feuilles de style et les fichiers js comportent des commentaires et des espaces inutiles pour un navigateur internet. Les ressources peuvent être minifiées directement dans le script gzip.php avec par exemple la librairie jsmin.php.
Autoriser la mise en cache par le navigateur
Une dernière optimisation est possible, la réécriture des liens vers les fichiers compressés. Pour l'instant, les feuilles de style ont un lien de type http://www.monsite.com/gzip.php?f=res/file.css, fichier qui ne sera pas mis en cache par les navigateurs internet.
Pour rendre le lien statique, editez le fichier htaccess à la racine du site internet avec un règle de réécriture de type:
#compress css,js
RewriteRule res/([\-[a-zA-Z0-9]*)\.css$ gzip.php?f=$1.css [L]
RewriteRule res/([\-[a-zA-Z0-9]*)\.js$ gzip.php?f=$1/$2/$3.js [L]