Optimisation de la mise en cache pour les templates Smarty

Discussion dans 'Administration d'un site Web' créé par Bigb06, 18 Août 2010.

  1. Bigb06
    Bigb06 WRInaute impliqué
    Inscrit:
    21 Mars 2007
    Messages:
    842
    J'aime reçus:
    1
    Bonjour,

    Il y a depuis peu pas mal de nouveaux topics sur l'optimisation du chargement des pages, voici ma petite contribution.
    La classe présentée, SmartyExtend, permet d'optimiser les performances des sites utilisant Smarty comme système de template. Cette classe gère la mise en cache des templates ainsi que l'ajout des entêtes d'expiration en accord avec le temps de mise en cache demandé.



    La classe:

    Code:
    <?php
    
    /**
     * Project:     SmartyExtend: permet d'améliorer la mise en cache des templates Smarty
     * File:        SmartyExtend.php
     *
     * This library is free software; you can redistribute it and/or
     * modify it under the terms of the GNU Lesser General Public
     * License as published by the Free Software Foundation; either
     * version 2.1 of the License, or (at your option) any later version.
     *
     * This library is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     * Lesser General Public License for more details.
     *
     * You should have received a copy of the GNU Lesser General Public
     * License along with this library; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     *
     * @author Nicolas Chevallier <nicolas.chevallier@b2b-net.com>
     * @version 1.0
     */
    
    
    class SmartyExtend extends Smarty{
    	
        public function __construct($tpl=null,$cache_time=0,$id=null)
        {
     		parent::__construct();
    
    		// si on ne veut pas utiliser de cache
    		if(is_null($tpl) || $cache_time == 0){
    			$this->caching = 0;
    		}
    		else{
    			// si on veut renouveller le fichier en cache
    			if(isset($_GET['clearcache']) && $_GET['clearcache'] == 'true'){
    				if($id!= null){
    					$this->clear_cache ($tpl,$id);
    				}else{
    					$this->clear_cache($tpl);
    				}
    			}
    			$this->caching = 2;
    			$this->cache_lifetime = $cache_time;
    			// Si le template est en cache, on l'affiche et on quitte
    			if($id!= null){
    				if($this->is_cached($tpl,$id)){
    					$this -> display( $tpl,$id_original);
    					exit(); 
    				}
    			}
    			else{
    				if($this->is_cached($tpl)){
    					$this -> display( $tpl );
    					exit(); 
    				}			
    			}
    		}	
    		//$this -> debugging = false;
    		//$this -> debugging_ctrl = (DEBUG_MODE == true) ? 'URL' : 'NONE';
        }
    
    
    	// surcharge de la fonction fetch pour améliorer les performances
    	// gestion des headers Expires et Cache control
        function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
        {
        	if(isset($_GET['next'])){
    			$cache_id = $cache_id.$_GET['next'];
    		}
            static $_cache_info = array();
            
            $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
                   ? $this->error_reporting : error_reporting() & ~E_NOTICE);
    
            if (!$this->debugging && $this->debugging_ctrl == 'URL') {
                $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
                if (@strstr($_query_string, $this->_smarty_debug_id)) {
                    if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
                        // enable debugging for this browser session
                        @setcookie('SMARTY_DEBUG', true);
                        $this->debugging = true;
                    } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
                        // disable debugging for this browser session
                        @setcookie('SMARTY_DEBUG', false);
                        $this->debugging = false;
                    } else {
                        // enable debugging for this page
                        $this->debugging = true;
                    }
                } else {
                    $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
                }
            }
    
            if ($this->debugging) {
                // capture time for debugging info
                $_params = array();
                require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
                $_debug_start_time = smarty_core_get_microtime($_params, $this);
                $this->_smarty_debug_info[] = array('type'      => 'template',
                                                    'filename'  => $resource_name,
                                                    'depth'     => 0);
                $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
            }
    
            if (!isset($compile_id)) {
                $compile_id = $this->compile_id;
            }
    
            $this->_compile_id = $compile_id;
            $this->_inclusion_depth = 0;
    
            if ($this->caching) {
                // save old cache_info, initialize cache_info
                array_push($_cache_info, $this->_cache_info);
                $this->_cache_info = array();
                $_params = array(
                    'tpl_file' => $resource_name,
                    'cache_id' => $cache_id,
                    'compile_id' => $compile_id,
                    'results' => null
                );
                require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
                if (smarty_core_read_cache_file($_params, $this)) {
                    $_smarty_results = $_params['results'];
                    if (!empty($this->_cache_info['insert_tags'])) {
                        $_params = array('plugins' => $this->_cache_info['insert_tags']);
                        require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
                        smarty_core_load_plugins($_params, $this);
                        $_params = array('results' => $_smarty_results);
                        require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
                        $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
                    }
                    if (!empty($this->_cache_info['cache_serials'])) {
                        $_params = array('results' => $_smarty_results);
                        require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
                        $_smarty_results = smarty_core_process_compiled_include($_params, $this);
                    }
    
    
                    if ($display) {
                        if ($this->debugging)
                        {
                            // capture time for debugging info
                            $_params = array();
                            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
                            $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
                            require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
                            $_smarty_results .= smarty_core_display_debug_console($_params, $this);
                        }
                        if ($this->cache_modified_check) {
                            $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
                            $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
                            $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
                            if (@count($this->_cache_info['insert_tags']) == 0
                                && !$this->_cache_serials
                                && $_gmt_mtime == $_last_modified_date) {
                                if (php_sapi_name()=='cgi')
                                    header('Status: 304 Not Modified');
                                else
                                    header('HTTP/1.1 304 Not Modified');
                            } else {
                            	// ajout de headers, le fichier est déja en cache
                            	// expires affecté à date de modification + temps de mise en cache
                            	header('Expires: ' . gmdate('D, d M Y H:i:s',$this->_cache_info['timestamp']+$this->cache_lifetime) . ' GMT');
    							//header('Cache-Control: max-age='.$this->cache_lifetime - ($this->_cache_info['timestamp'] - time()));
                                header('Last-Modified: '.$_gmt_mtime);
                                echo $_smarty_results;
                            }
                        } else {
                                echo $_smarty_results;
                        }
                        error_reporting($_smarty_old_error_level);
                        // restore initial cache_info
                        $this->_cache_info = array_pop($_cache_info);
                        return true;
                    } else {
                        error_reporting($_smarty_old_error_level);
                        // restore initial cache_info
                        $this->_cache_info = array_pop($_cache_info);
                        return $_smarty_results;
                    }
                } // pas de fichier cache present
                 else {
                    $this->_cache_info['template'][$resource_name] = true;
                    if ($this->cache_modified_check && $display) {
                        // ajout de headers, on vient de créer le fichier
                        // expires affecté now + à temps de mise en cache
                        header('Expires: ' . gmdate('D, d M Y H:i:s',time()+$this->cache_lifetime) . ' GMT');
    					//header('Cache-Control: max-age='.$this->cache_lifetime);
                        header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
                    }
                }
            }
    
            // load filters that are marked as autoload
            if (count($this->autoload_filters)) {
                foreach ($this->autoload_filters as $_filter_type => $_filters) {
                    foreach ($_filters as $_filter) {
                        $this->load_filter($_filter_type, $_filter);
                    }
                }
            }
    
            $_smarty_compile_path = $this->_get_compile_path($resource_name);
    
            // if we just need to display the results, don't perform output
            // buffering - for speed
            $_cache_including = $this->_cache_including;
            $this->_cache_including = false;
            if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
                if ($this->_is_compiled($resource_name, $_smarty_compile_path)
                        || $this->_compile_resource($resource_name, $_smarty_compile_path))
                {
                    include($_smarty_compile_path);
                }
            } else {
                ob_start();
                if ($this->_is_compiled($resource_name, $_smarty_compile_path)
                        || $this->_compile_resource($resource_name, $_smarty_compile_path))
                {
                    include($_smarty_compile_path);
                }
                $_smarty_results = ob_get_contents();
                ob_end_clean();
    
                foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
                    $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
                }
            }
    
            if ($this->caching) {
                $_params = array('tpl_file' => $resource_name,
                            'cache_id' => $cache_id,
                            'compile_id' => $compile_id,
                            'results' => $_smarty_results);
                require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
                smarty_core_write_cache_file($_params, $this);
                require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
                $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
    
                if ($this->_cache_serials) {
                    // strip nocache-tags from output
                    $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
                                                    ,''
                                                    ,$_smarty_results);
                }
                // restore initial cache_info
                $this->_cache_info = array_pop($_cache_info);
            }
            $this->_cache_including = $_cache_including;
    
            if ($display) {
                if (isset($_smarty_results)) { echo $_smarty_results; }
                if ($this->debugging) {
                    // capture time for debugging info
                    $_params = array();
                    require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
                    $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
                    require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
                    echo smarty_core_display_debug_console($_params, $this);
                }
                error_reporting($_smarty_old_error_level);
                return;
            } else {
                error_reporting($_smarty_old_error_level);
                if (isset($_smarty_results)) { return $_smarty_results; }
            }
        }
    }//end of class
    ?>

    Un exemple d'utilisation :
    On prend l'exemple d'une fiche avec un paramètre id
    Code:
    <?php
    // chargements des bibliothèques et inclusions...
    $smarty = new SmartyExtend('template.tpl',24*60*60,$_GET["id"]);// mise en cache 24h
    
    // Le code ci dessous ne sera éxécuté que si le template n'est pas en cache
    
    // affichage et stockage du template une fois les traitements effectués
    $content = $smarty -> fetch( 'template.tpl',$_GET["id"]); 
    echo $content; 
    
    ?>
    
    Dans cet exemple la page ne sera générée qu'une fois toutes les 24h, et la date d'expiration correspondra à la fin de la mise en cache. Cela permet à GoogleBot de connaître la date de prochain passage optimale, et aux visiteurs de garder en cache le fichier html (plus aucune requête ne sera nécessaire si les Etags sont désactivés). Pour regénérer une fiche il suffit d'ajouter ?clearcache=true à la fin de l'url.
     
  2. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 176
    J'aime reçus:
    327
Chargement...
Similar Threads - Optimisation cache templates Forum Date
Optimisation mise en cache avec google PageSpeed Insights Google Analytics 21 Août 2017
Optimisation d'une page : Titre du Site et Menu comment les inclure? Débuter en référencement 13 Septembre 2021
Astuce Optimisation des URLs Débuter en référencement 15 Juin 2021
WordPress PageSpeed - optimisation - fonts Développement d'un site Web ou d'une appli mobile 27 Janvier 2021
Optimisation SXO de site web de mon agence Référencement Google 22 Janvier 2021
Avis et optimisation sur blog voyage Demandes d'avis et de conseils sur vos sites 24 Décembre 2020
Optimisation du Cumulative Layout Shift (CLS) Référencement Google 8 Décembre 2020
Optimisation URL pour les moteurs de recherche Débuter en référencement 15 Novembre 2020
Optimisation site Wordpress Débuter en référencement 21 Août 2020
Optimisation des publicités / revenus AdSense 19 Juillet 2020