Valider 3cc452c6 rédigé par esj's avatar esj
Parcourir les fichiers

Suppression de la décompression d'un cache quand il n'a pas besoin de...

Suppression de la décompression d'un cache quand il n'a pas besoin de post-traitements et que le navigateur accepte le format compressé Deflate utilisé par SPIP pour gérer son cache. Les tests réalisés font apparaître un gain de 10% dans le temps de rendu de la page par les navigateurs.

Les post-traitements sont effectués par public.php soit par un code explicite, soit par les déclarations dans le pipeline "affichage_final", lequel était en standard garni avec 3 fonctions. Elles en ont été retirées et rendues explicites dans public.php, car ce pipeline impose de décompresser pour savoir s'il faut décompresser ! Voici les post-traitements qu'il faut essayer d'éviter pour obtenir l'optimisation:

 * les squelettes de premier niveau comportant des interpolations de PHP nécessitent un post-traitement; il faut les éviter, en particulier utiliser "#INCLURE" plutôt que la version où "#" est remplacé par un chevron ouvrant;

 * si la profondeur d'URL n'est pas nulle et qu'une balise base avec attribut Href en absolu ne figure pas dans le squelette, l'introduction de cette balise est nécessaire; mettre cette balise dans le squelette est préférable, et sa présence est testée lors de la mise en cache afin de disposer de l'information sans nécessité de décrompression;

 * un post traitement de surlignage est effectué si la requête comporte "var_recherche" et possède un Referer; à noter que ce code est lié au  filtre url_var_recherche de la 1.9.2 et qui a disparu en 2.0 bizarrement (il ne figure pas dans le r12702 qui l'a créée, alors que la 1.9.2 a continué à l'améliorer jusqu'à la r14826). De plus un AND a été tranformé en OR à un moment, ce qui faisait invoquer cette fonction dès qu'un Referer était présent. Sauf plugin inconnu, je pense que ce code est complètement mort et devrait être supprimé;

 * un post-traitement est nécessaire si on demande la validation XML de la page (seulement accessible aux admins);

 * un post-traitement est nécessaire en cas de bouton admin (même remarque).

Enfin, si une version compressée n'est pas envoyable (inexistante ou ayant nécessité décompression) SPIP effectue la compression si le panneau de configuration l'a demandé. Ce bout de code de 3 lignes fait donc le boulot de l'extension "compresseur" qui a le défaut de tenter de compresser les envois par le script "acceder_document" et sort en erreur quand ils sont trop gros. Il peut donc être retirer de la distribution sans perte de fonctionnalité.
parent b2fce353
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+1 −1
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -264,7 +264,7 @@ $spip_pipeline = array(
	'accueil_gadgets' => '',
	'accueil_informations' => '',
	 # cf. public/assembler
	'affichage_final' => '|f_surligne|f_tidy|f_admin',
	'affichage_final' => '',
	'affichage_entetes_final' => '',
	'afficher_fiche_objet'=>'',
	'afficher_config_objet' => '',
+60 −11
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -163,6 +163,7 @@ if (isset($GLOBALS['_INC_PUBLIC'])) {
	// inclure_balise_dynamique nous enverra peut-etre
	// quelques en-tetes de plus (voire qq envoyes directement)

        gunzip_page($page);
		// restaurer l'etat des notes
		if (isset($page['notes']) AND $page['notes']){
			$notes = charger_fonction("notes","inc");
@@ -192,13 +193,46 @@ if (isset($GLOBALS['_INC_PUBLIC'])) {
			erreur_squelette($msg);
	}
	//
	// Post-traitements
	// Post-traitements pour pages HTML (font perdre la compression initiale)
	//
	page_base_href($page['texte']);
	if ($html) {
        // S'il faut inserer une balise Base du fait de profondeur_url > 0
        if (page_base_define()) {
            // Compatibilite vieux caches
            if (!isset($page['base'])) {
                gunzip_page($page);
                $page['base']= page_base_presente($page['texte']);
            }
            if ($page['base']) {
                gunzip_page($page);
                page_base_href($page['texte'], $page['base']);
            }
        }
        // S'il faut surligner une recherche
        // ce code semble mort, car dependant du filtre url_var_recherche
        // de la 1.9.2 disparu en 2.0. Y a un plugin qui s'en sert ?
        if (_request('var_recherche') AND isset($_SERVER['HTTP_REFERER'])) {
            gunzip_page($page);
            include_spip('inc/surligne');
            $page['texte'] = surligner_mots($page['texte'], _request('var_recherche'));
        }
        // Si on veut appliquer un validateur local
        if ($xhtml) {
            gunzip_page($page);
            $page['texte'] = f_tidy($page['texte']);
        }
        // Si on a un cookie de session d'admin
        if ($affiche_boutons_admin) {
            gunzip_page($page);
            $page['texte'] = f_admin($page['texte']);
        }
    }

	// (c'est ici qu'on fait var_recherche, validation, boutons d'admin,
	// cf. public/assembler.php)
	// Ce pipeline fait perdre la possibilite d'envoyer la version compressee
    if ($spip_pipeline['affichage_final']) {
        gunzip_page($page);
        $page['texte'] = pipeline('affichage_final', $page['texte']);
    }

	// Ces dernieres operations ont pu lever des erreurs (inclusion manquante)
	// il faut tester a nouveau 
@@ -206,15 +240,30 @@ if (isset($GLOBALS['_INC_PUBLIC'])) {
	$debug = ((_request('var_mode') == 'debug') OR $tableau_des_temps) ? array(1) : array();

    // Si pas d'ajout ulterieur, 
    // fournir Content-Length et compresser si possible et utile
    if (!$debug) {
        if (($page['entetes']['Content-Length'] = strlen($page['texte']))>8192)
            if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !==false) {
    // fournir Content-Length et compresser si possible, utile et pas deja fait
    if ($debug) {
        gunzip_page($page);
    } else {
        // si page deja compressee la servir comme ca si possible
        if ($page['gz'] == 'deflate') {
            if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !==false) {
                $page['entetes']['Content-Length'] = strlen($page['texte']);
                $page['entetes']['Content-Encoding'] = 'deflate';
#                spip_log("gain d'une decompression pour $fond");
            } else gunzip_page($page);
        }
        // si pas compressee ou decompressee a l'instant, essayer en gzip
        if ($page['gz'] != 'deflate') {
            $page['entetes']['Content-Length'] = strlen($page['texte']);
            if (($page['entetes']['Content-Length']>8192)
            AND ($GLOBALS['meta']['auto_compress_http'] == 'oui')
            AND (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !==false)) {
                    $page['texte'] = gzencode($page['texte']);
                    $page['entetes']['Content-Encoding'] = 'gzip';
                    $page['entetes']['Content-Length'] = strlen($page['texte']);
            }
        }
    }
    envoyer_entetes($page['entetes']);
    echo $page['texte'];

+62 −55
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -67,6 +67,7 @@ function assembler($fond, $connect='') {
		if (!$page) $page['status'] = 204;
		$page['entetes']["Connection"] = "close";
		$page['texte'] = "";
		$page['gz'] = false;
		// Ne pas ajouter le bouton admin!
		$flag_preserver = true;

@@ -276,6 +277,14 @@ function inclure_page($fond, $contexte, $connect='') {
	// dans tous les cas, mettre a jour $lastmodified
	$lastmodified = max($lastmodified, $lastinclude);

    if (is_array($page)) {
        gunzip_page($page);
        // compatibilite vieux cache:
        // indiquer s'il manque la balise base alors qu'elle devrait
        if (!isset($page['base']))
            $page['base']= page_base_presente($page['texte']);
    }

	return $page;
}

@@ -386,15 +395,9 @@ function inclure_balise_dynamique($texte, $echo=true, $contexte_compil=array())

}

// Traiter var_recherche ou le referrer pour surligner les mots
// obsolete
// http://doc.spip.org/@f_surligne
function f_surligne ($texte) {
	if (!$GLOBALS['html']) return $texte;
	$rech = _request('var_recherche');
	if (!$rech AND !isset($_SERVER['HTTP_REFERER'])) return $texte;
	include_spip('inc/surligne');
	return surligner_mots($texte, $rech);
}
function f_surligne ($texte) { return $texte;}

// Valider/indenter a la demande.
// http://doc.spip.org/@f_tidy
@@ -620,7 +623,8 @@ function evaluer_fond ($fond, $contexte=array(), $connect=null) {
		$page['process_ins'] = 'html';
		ob_end_clean();
	}
	page_base_href($page['texte']);
    if (page_base_define())
        page_base_href($page['texte'], $page['base']);

	// Lever un drapeau (global) si le fond utilise #SESSION
	// a destination de public/parametrer
@@ -645,38 +649,12 @@ function xml_hack(&$page, $echap = false) {
}

// http://doc.spip.org/@page_base_href
function page_base_href(&$texte){
	if (!defined('_SET_HTML_BASE'))
		// si la profondeur est superieure a 1
		// est que ce n'est pas une url page ni une url action
		// activer par defaut
		define('_SET_HTML_BASE',
			$GLOBALS['profondeur_url'] >= (_DIR_RESTREINT?1:2)
			AND _request(_SPIP_PAGE) !== 'login'
			AND !_request('action'));

	if (_SET_HTML_BASE
	AND isset($GLOBALS['html']) AND $GLOBALS['html']
	AND $GLOBALS['profondeur_url']>0
	AND ($poshead = strpos($texte,'</head>'))!==FALSE){
		$head = substr($texte,0,$poshead);
		$insert = false;
		if (strpos($head, '<base')===false) 
			$insert = true;
		else {
			// si aucun <base ...> n'a de href c'est bon quand meme !
			$insert = true;
			include_spip('inc/filtres');
			$bases = extraire_balises($head,'base');
			foreach ($bases as $base)
				if (extraire_attribut($base,'href'))
					$insert = false;
		}
		if ($insert) {
function page_base_href(&$texte, $poshead){
    include_spip('inc/filtres_mini');
    // ajouter un base qui reglera tous les liens relatifs
    $base = url_absolue('./');
    $bbase = "\n<base href=\"$base\" />";
    $head = substr($texte,0,$poshead);
    if (($pos = strpos($head, '<head>')) !== false)
        $head = substr_replace($head, $bbase, $pos+6, 0);
    elseif(preg_match(",<head[^>]*>,i",$head,$r)){
@@ -690,7 +668,36 @@ function page_base_href(&$texte){
    if (strpos($texte, "href=\"#")!==false)
        $texte = str_replace("href=\"#","href=\"$base#",$texte);
}

function page_base_presente($texte)
{
    $insert = strpos($texte,'</head>');
    if ($insert === false) return false;
    $head = substr($texte, 0, $insert);
     if (strpos($head, '<base')===false) 
         return $insert;
    else {
        // si aucun <base ...> n'a de href c'est bon quand meme !
        include_spip('inc/filtres');
        $bases = extraire_balises($head,'base');
        foreach ($bases as $base)
            if (extraire_attribut($base,'href'))
                return false;
    }
    return $insert;
}

function page_base_define()
{    
    if (!defined('_SET_HTML_BASE'))
        // si la profondeur est superieure a 1
        // et que ce n'est pas une url page ni une url action
        // activer par defaut
        define('_SET_HTML_BASE',
				$GLOBALS['profondeur_url'] >= (_DIR_RESTREINT?1:2)
				AND _request(_SPIP_PAGE) !== 'login'
				AND !_request('action'));
    return _SET_HTML_BASE;
}

function public_previsualisation_dist($page)
+13 −17
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -55,12 +55,10 @@ function generer_nom_fichier_cache($contexte, $page) {
}

// Faut-il compresser ce cache ? A partir de 16ko ca vaut le coup
// (pas de passage par reference car on veut conserver la version non compressee
// pour l'afficher)
// http://doc.spip.org/@gzip_page
function gzip_page($page) {
	if (function_exists('gzcompress') AND strlen($page['texte']) > 16*1024) {
		$page['gz'] = true;
		$page['gz'] = 'deflate';
		$page['texte'] = gzcompress($page['texte']);
	} else {
		$page['gz'] = false;
@@ -68,13 +66,12 @@ function gzip_page($page) {
	return $page;
}

// Faut-il decompresser ce cache ?
// (passage par reference pour alleger)
// Decompresser ce cache au besoin
// http://doc.spip.org/@gunzip_page
function gunzip_page(&$page) {
	if ($page['gz']) {
		$page['texte'] = gzuncompress($page['texte']);
		$page['gz'] = false; // ne pas gzuncompress deux fois une meme page
		$page['gz'] = false;
	}
}

@@ -143,6 +140,13 @@ function creer_cache(&$page, &$chemin_cache) {
		OR defined('spip_interdire_cache'))
		return;

	// ajouter la date de production dans le cache lui meme
	// (qui contient deja sa duree de validite)
	$page['lastmodified'] = time();

    // indiquer s'il manque la balise base alors qu'elle devrait
	$page['base']= page_base_presente($page['texte']);

	// Si la page c1234 a un invalideur de session 'zz', sauver dans
	// 'tmp/cache/MD5(chemin_cache)_zz'
	if (isset($page['invalideurs'])
@@ -152,7 +156,6 @@ function creer_cache(&$page, &$chemin_cache) {
		// des caches sessionnes
		if (!lire_fichier(_DIR_CACHE . $chemin_cache, $tmp)
		OR !$tmp = @unserialize($tmp)) {
			spip_log('Creation cache sessionne '.$chemin_cache);
			$tmp = array(
				'invalideurs' => array('session' => ''),
				'lastmodified' => time()
@@ -162,14 +165,9 @@ function creer_cache(&$page, &$chemin_cache) {
		$chemin_cache .= '_'.$page['invalideurs']['session'];
	}

	// ajouter la date de production dans le cache lui meme
	// (qui contient deja sa duree de validite)
	$page['lastmodified'] = time();


	// l'enregistrer, compresse ou non...
	$ok = ecrire_fichier(_DIR_CACHE . $chemin_cache,
		serialize(gzip_page($page)));
	$zpage = gzip_page($page);
	$ok = ecrire_fichier(_DIR_CACHE . $chemin_cache, serialize($zpage));

	spip_log("Creation du cache $chemin_cache pour "
		. $page['entetes']['X-Spip-Cache']." secondes". ($ok?'':' (erreur!)'));
@@ -177,7 +175,7 @@ function creer_cache(&$page, &$chemin_cache) {
	// Inserer ses invalideurs
	include_spip('inc/invalideur');
	maj_invalideurs($chemin_cache, $page);

	$page = $zpage;
}


@@ -291,7 +289,6 @@ function public_cacher_dist($contexte, &$use_cache, &$chemin_cache, &$page, &$la
		$page['contexte_implicite'] = $contexte_implicite;
		if (!$use_cache) {
			// $page est un cache utilisable
			gunzip_page($page);
			return;
		}
	} else {
@@ -302,7 +299,6 @@ function public_cacher_dist($contexte, &$use_cache, &$chemin_cache, &$page, &$la
	// Si pas valide mais pas de connexion a la base, le garder quand meme
	if (!spip_connect()) {
		if (isset($page['texte'])) {
			gunzip_page($page);
			$use_cache = 0;
		}
		else {