Posts Tagged ‘performance’

Coder un thème WordPress : bonnes pratiques

Lundi, juin 15th, 2009

Un thème WordPress bien codé peut alléger la charge du serveur et augmenter la rapidité de chargement des pages.
Par ailleurs, vous gagnerez en facilité de maintenance en rationalisant l’organisation de votre thème.

Restez léger, codez proprement, utilisez le cache WordPress, allégez votre header.php, utilisez un sous domaine en CDN.
Exemple de fichier functions.php.


Codez et voyagez léger

  • De facon générale, le minimum de PHP dans vos fichiers de theme. Le fichier functions.php (à placer dans le même répertoire que vos fichiers de thème single.php, index.php, etc.) est fait pour contenir les fonctions PHP qui serviront dans le thème. En particulier :
    • Pas d’interrogation RSS dans les thèmes
    • Pas de requêtes MySQL lourdes dans les thèmes
    • Le minimum de lignes PHP : si vous venez d’ajouter plus de 3 lignes de PHP à la suite dans votre thème, vous feriez mieux d’en faire une fonction.
  • Autant que possible, essayez de spécifiez les dimensions des images dans vos balises <img>. C’est systématique pour les images statiques (images de sidebar); en revanche pour les images dynamiques (dans les billets), c’est moins important.
  • Pensez à compresser/minifier vos fichiers CSS et JS. Utilisez un compresseur de Javascript pour créer des versions « pack » de vos fichiers Javascript. Utilisez votre éditeur favori pour formatez vos CSS « en ligne »
  • Utilisez des noms de classes courts dans vos fichiers CSS, surtout pour les classes répétitives. #h au lieu de #header n’économisera pas grand chose, mais .ost au lieu de .odd_strong_title peut avoir un impact (on gagne quelques % sur la longueur du fichier HTML)

Coder proprement, et dans le style WordPress

Dans votre template :

<?php faire_quelque_chose('var=val&var2=val2'); ?>

Dans le fichier functions.php :

<?php
function faire_quelque_chose($args = '') {
  $defaults = array(
    'var' => 'valeur par defaut',
    'var2' => 'valeur par defaut',
    'echo' => 1,
    );
  $args = wp_parse_args($args,$defaults);
  extract($args,EXTR_SKIP);
  // vous pouvez maintenant utiliser les variables $var et $var2
  // $output =  "resultat de la fonction: $var est var et var2 est $var2";
  // ajouter un filtre avant de retourner est une bonne pratique, qui permet d'ajouter une couche plugin a vos fonctions de theme
  $output = apply_filters('faire_quelque_chose',$output);
  if($echo) echo $output;
  else return $output;
  }

Utiliser le cache WordPress

Rien de plus simple, et ca peut vous économiser beaucoup de charge :

Sans cache :

function afficher_quelque_chose() {
  $output = "une opération longue et compliquée";
  echo $output;
  }
function faire_qqchose_post($post_id) {
  $value = "operation compliquée avec des get_post et plein de choses compliquées";
  return $value;
  }

Avec cache :

function afficher_quelque_chose() {
  if(!$output = wp_cache_get('afficher_quelque_chose')) {
    $output = "une opération longue et compliquée";
    wp_cache_add('afficher_quelque_chose',$output);
    }
  echo $output;
  }
function faire_qqchose_post($post_id) {
  if(!$value = wp_cache_get("faire_qqchose_$post_id")) {
    $value = "operation compliquée avec des get_post et plein de choses compliquées";
    wp_cache_add("faire_qqchose_$post_id",$value);
  }
  return $value;
  }

Le cache ne sera effectif que si vous avez le plugin WP Super Cache activé en mode HalfOn ou On.


Garder un header.php léger : ajout dynamique du style et des scripts

Voici un exemple de début de fichier header.php, sur un site de mes clients, un site particulièrement chargé en trafic et très intégré :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
<title><?php wp_title(); ?></title>
<!--wp_head-->
<?php wp_head(); ?><!--//wp_head-->
</head>

Compliqué, n’est ce pas ? Il y a pourtant plus de 10 scripts JS et 5 feuilles de style sur ce site.
Une fois tout installé, voici un exemple de header généré :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" class="fr-FR">
<head profile="http://gmpg.org/xfn/11">
<!-- les deux lignes suivantes sont ajoutés par PHP Speedy, il s'agit du JavaScript et du CSS compressé -->
<link type="text/css" href="http://lesite.com/wp-content/plugins/php_speedy_wp/cache/_cmp_cssstylesheet_aaaabe17ccfd921696e24d48176f17b6.php" rel="stylesheet" />
<script type="text/javascript" src="http://lesite.com/wp-content/plugins/php_speedy_wp/cache/_cmp_javascript_57b933498ac7eff7b75fe9dd997b5cb0.php"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>titre généré</title>
<!--wp_head-->
<!-- tout ce qui suit est rajouté de facon dynamique -->
<!-- rajoute par le theme -->
<link href="/favicon.ico" rel="shortcut icon" />
<script type="text/javascript">if(top!=self) {top.location=self.location;}</script>
<!--[if IE]><link rel="stylesheet" href="http://lesite.com/wp-content/themes/lesite/ie.css" type="text/css" media="screen, projection" /><![endif]-->
<!-- les lignes qui suivent sont rajoutés en standard par WordPress -->
<link rel="alternate" type="application/rss+xml" title="Jeux Géographiques RSS Feed" href="http://lesite.com/feed/" />
<link rel="alternate" type="application/atom+xml" title="Jeux Géographiques Atom Feed" href="http://lesite.com/feed/atom/" />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://lesite.com/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://lesite.com/wp-includes/wlwmanifest.xml" />
<meta name="generator" content="WordPress 2.7" />
<meta name="description" content="Description." />
<meta name="keywords" content="keywords" />
<!--//wp_head-->
</head>

Il n’y a aucune raison de charger plus que ca le fichier header.php.

Pour ajouter dynamiquement les fichiers JS et CSS, utilisez les fonctions wp_enqueue_style et wp_enqueue_script
Usage :

wp_enqueue_script($handle,$src,$dependances,$version,$in_footer); // $in_footer pour WP 2.8+
wp_enqueue_style($handle,$src,$dependances,$version,$media);

En voir plus dans le fichier exemple


Utiliser un sous domaine pour servir les fichiers

En raison des limites des requêtes HTTP (principalement, 4 fichiers servis par sous domaine simultanément), vous gagnerez de la rapidité en servant vos fichiers CSS, JS et images à partir d’un sous domaine.
Une solution simple est de configurer un sous domaine qui pointe à la même adresse que votre site principal.
Exemple: www.malaiac.net et medias.malaiac.net pointent vers le même répertoire.

Vous pouvez ensuite modifier les adresses de certains de vos fichiers (par exemple, les images), ou bien filtrer tout les JS et CSS :

Dans functions.php :

// a modifier avec votre sous domaine ou CDN
//define('CDN_ADDRESS','http://medias.malaiac.net');
function get_cdn_address() {
  if(!defined('CDN_ADDRESS')) return get_option('home');
  return CDN_ADDRESS;
}
function add_cdn_address($bloginfo,$output = '', $show= '') {
  if(!in_array($output,array('stylesheet_url','stylesheet_directory','template_directory','template_url'))) return $bloginfo;
  $bloginfo = str_replace(get_option('home'),get_cdn_address(),$bloginfo);
  return $bloginfo;
}
add_filter('bloginfo_url','add_cdn_address',10,2);
/** attention à modifier :
 * get_bloginfo('template_directory');
 * en :
 * get_bloginfo('template_directory','display');
 * pour que le filtre soit appellé
 **/
/**
 * Pour afficher une image dans votre thème, utilisez :
 * 
 **/

Utilisez Ajax pour charger les éléments lourds

Certains éléments n’ont aucun intérêt pour le référencement, et prennent beaucoup de temps à charger.
Exemple : les mosaiques de gravatars des derniers commentaires ; une image lourde qui sert d’illustration.

Vous pouvez charger ces éléments en Ajax, exemple :

<div id="contenulourd"></div>
<script type="text/javascript">
jQuery(document).ready(function() {
	jQuery.ajax({
		type: 'POST',
		url: '<?php get_bloginfo('template_directory','display') ?>/ajax.php',
		data: {action: 'contenulourd'},
		success: function(response) {
			jQuery('#contenulourd').html(response);
			},
	});
	}
});
</script>

Dans votre répertoire de thème, ajoutez un fichier ajax.php :

<?php
header("text/html; charset=UTF-8");
// si vous avez besoin de charger WordPress
//include('../../../wp-load.php');
if($_POST['action'] == 'contenulourd') {
  echo "<div>plein de contenu avec des <img> bien chargées et des <p>contenus bien lourds</p>";
  }
}

Une base de fichiers functions.php

// si vous avez un fichier de traduction, à nommer fr_FR.mo
load_theme_textdomain('theme');
function theme_init() {
  // setlocale permet de préciser la langue et le charset à utiliser si besoin
  // setlocale(LC_ALL, 'fr_FR@euro', 'fr_FR', 'fra_fra');
  // ajout JS et CSS
  $template_dir = get_bloginfo('template_directory','display');
  wp_enqueue_style('style_css',$template_dir.'/style.css',array(),false,'screen,projection');
  wp_enqueue_style('print_css',$template_dir.'/print.css',array(),false,'print');
  // ce script se chargera en pied de page
  wp_enqueue_script('theme_js_footer',$template_dir.'/functions.js',array('jquery'),false,1);
  // ajout d'un script avec des chaines de traduction :
  wp_enqueue_script('theme_js',$template_dir.'/functions.js',array('jquery'));
  wp_localize_script('theme_js','themeL10n',array(
    'no' => __('No','theme'),
    'thanks' => __('Thanks','theme'),
    ));
  // ces chaines seront disponibles dans le javascript avec : themeL10n.thanks
  }
// pour WP2.8+
add_action('wp_enqueue_scripts', 'theme_init');
// pour WP < 2.8, dans ce cas, rajouter if(is_admin()) return; au début de la fonction
add_action('init','theme_init',8); //
// cette fonction se lance entre <head> et </head>
function theme_wp_head() {
  if(is_admin()) return;
  // exemple de ligne
  echo '
';
  }
add_action('wp_head','theme_wp_head',8);
// cette fonction peut servir à filter les headers 301 et 404 (redirections, héritages, etc.)
function theme_header($header) {
  if($header == 'HTTP/1.1 301 Moved Permanently') {
    // faire qqchose
  }
  elseif($header == 'HTTP/1.1 404 Not Found') {
    // faire qqchose
  }
  return $header;
  }
add_filter('status_header','theme_header');

Optimisation WordPress

Mercredi, juin 10th, 2009

L’énergie la moins chère c’est celle qu’on ne dépense pas
HTTP + WordPress + PHP + MySQL = cher
Cache = pas cher

Pourquoi optimiser ? et pourquoi optimiser WordPress ?
Comment mesurer l’optimisation d’un site, avec Pingdom, Firebug, Yahoo Slow et Google Page Speed

Optimisation des performances de WordPress :
Sur Apache, en ajoutant des headers Expire, en compressant le contenu, en ajoutant des Etags, en utilisant des sous domaines, en installant un opcode cache
Du coté MySQL, en activant le cache et en loggant les requêtes longues.
Sur WordPress, en faisant attention aux plugins, en activant le cache avec WP Super Cache, en rassemblant les fichiers JS et CSS avec PHP Speedy, en désactivant la sauvegarde automatique

(Lire la suite…)

Les poulets à la vitesse du cheval

Samedi, février 14th, 2009

radar

Les nouveaux radars, et non ce n’est pas la police montée…

Attention à votre vitesse en campagne.

(EDIT : il s’agit d’une photo prise en Angleterre, mais d’ici que la police francaise chope l’idée…)