Ecole des Mines de Gardanne : les bases du Web – optimisation – sécurité
Ecole des Mines de Gardanne : après cette journée passée de cours voici, à la demande de plusieurs élèves, les cours
Ecole des Mines de Gardanne : après cette journée passée de cours voici, à la demande de plusieurs élèves, les cours
Mon site de démonstration pour l’utilisation du framework Symfony 2 est sorti.
Ce n’est qu’un site de démonstration, il est loin d’être parfait !
Si vous avez des commentaires ou suggestions à faire, n’hésitez pas !
Voici le score obtenu de mon site basé sur mon framework :
Que dois-je dire de plus ?
…
Je peux expliquer quelles sont toutes les bonnes pratiques ! Mais uniquement si on me le demande !
Après avoir fait ma présentation, cela fait toujours plaisir de savoir qu’on est suffisamment intéressé pour demander ma présentation !
Cliquez sur le lien pour la récupérer, et n’hésitez pas à laisser une appréciation sur ce qui était bien et ce qui manquait éventuellement, sachant que j’ai fait ce que je pouvais dans un laps de temps aussi court 😉
Cliquez ici.
Sur la toute dernière version de Smarty (3.1), voici comment créer un plugin personnalisé.
Pour résumer, l’un de mes sites n’était pas assez optimisé.
Le code qui sortait était :
<body class="sbody">
<div>
....
</div>
....
</body>
J’ai donc ajouté le filtre d’optimisation qui supprime les espaces en début :
$this->smarty->loadFilter('output', 'trimwhitespace');
Le code de sortie est devenu :
<body class="sbody"><img src="/title.jpg" /><div>....</div>....</body>
Tout mise en une ligne, super !
Le seul problème, c’est que ça ne fonctionnait pas avec le code JavaScript, il faut en effet les retours à la ligne.
J’ai donc crée mon plugin qui ne fait que supprimer les espaces en début de ligne, et remplacer de « retour + line feed » (deux octets) de fin de ligne par un seul octet « retour ».
Voici le code, je vous laisse comprendre, c’est extrêmement simple :
/* Déclarer un plugin "block". * Block = il faut un début et une fin. * Ici : {triml} {/triml} */ $this->smarty->registerPlugin('block', 'triml', array($this,'smarty_block_trim_l'));
Après avoir déclaré le plugin, il faut faire la fonction adéquate :
/** * Fonction de plugin smarty pour supprimer tous les espaces * en début de ligne entre les blocs {triml}{/triml} * "triml" = trimleft * Voir le constructeur et chercher $this->smarty->registerPlugin() * * @param array $params les paramètres qu'on passe à {strip_nl} * @param variant $content Le contenu qu'il y a dans le bloc * @param variant $template Le nom du template * @param variant &$repeat * * @return int Description retour */ public function smarty_block_trim_l( array $params, $content, $template, &$repeat) { $content = preg_replace('/\n[\s]+/', "\n", $content); return $content; }
Et voilà maintenant, vous pourrez aussi optimiser votre site comme un professionnel.
Bien évidemment le gain le plus gros est dans la compression (voir mod_deflate)
Saviez vous que Facebook a eu une idée assez intéressante ?
Ils ont crée un outil qui transforme le code Php en code C++ et qu’on peut donc compiler.
D’ailleurs la plupart des choses de FaceBook tournent via cet outil, pour accélérer et optimiser au maximum leur site.
Il est ainsi possible de pousser la performance Php à l’extrême.
Pour ceux qui veulent rendre leur site encore plus rapide, voici le lien :
Merci à Mathieu Robin, ici, pour les petites explications de jQuery 1.5, dans lequel on peut lire qu’ils ont laissé tomber Google Closure Compiler pour UglifyJS.
UglifyJS est une librairie de compression/optimisation de code JavaScript. Dit autrement, vous écrivez votre code en JavaScript, vous le testez, avec les commentaires et tout et tout, et puis dès que vous pensez qu’il est prêt, hop, vous le passez à la moulinette UglifyJS et vous aurez un code super compressé, sans aucun commentaire, mais qui fonctionnera à l’identique de l’original, et vous pourrez le mettre sur votre serveur de production.
PS : Si si il est bien 2:44 du matin, j’ai fini de donner le bib’ à mon fils (^_^)
Attention, ce qui suit ne s’applique pas systématiquement partout, mais il faut avoir cela en tête dans certaines occasions.
Ci-suivent deux possibilités de codes qui font exactement la même chose : vous allez certainement me dire : le code 2 est très nettement moins bien que le code 1, à savoir que si on veut rajouter quelque chose dans le 1 c’est une ligne alors que dans le 2 c’est quatre lignes. Eh bien c’est vrai, mais il faut garder le code 2 qui est plus long et qui semble se répéter de manière inutile. Pourquoi, me demanderez-vous ? Je vais vous dire pourquoi :
Si, si, je ne plaisante pas. Si vous avec un patron qui vous dit, une bonne fois pour toutes : « Voilà les champs qu’on utilisera cela ne changera pas », et, surtout, que c’est vrai, alors vous pouvez vous faire plaisir et factoriser au maximum. A l’inverse, un patron qui arrive et qui vous dit « Voilà les champs qu’on utilisera cela ne changera pas », et, le connaissant vous savez que c’est faux, alors utilisez le code 2. Cela m’arrive tout le temps : « Au fait Olivier j’ai oublié de te dire : il y a un nouveau champ garantie qui est, en réalité un pourcentage d’une autre garantie et il faut s’assurer que l’autre existe vraiment ». Si vous avez adopté le code 1 avec ce genre de patron, vous êtes fichu : Ce code n’est pas prévu pour gérer des exceptions.
Dernier argument pour le code 2 : il est beaucoup plus compréhensible que le code 1. Beaucoup, beaucoup, beaucoup. Et si quelqu’un doit prendre le relai après vous, votre objectif en tant que professionnel, c’est de lui faciliter la tâche au maximum. Donc… vive le code 2 !
private function CreerTableauValeursGarantie($gar,$tab)
{
foreach ($tab as $fc_aff=>$tab_get) {
if ($gar->$fc_aff()) {
foreach ($tab_get as $idx=>$fc_get) {
$ret[$idx]=$gar->$fc_get();
}
}
}
}
$tab_gar[$id_g][$idp_idf] =
$this->CreerTableauValeursGarantie($gar, array(
'getAffSurmortalite' => array(
VAL_SURMORTALITE => 'getTauxSurprime2'),
'getAffSurprime1' => array(
VAL_SURPRIME_ADDITIONNELLE_DUREE_1 => 'getSurprimeAddDuree1',
VAL_SURPRIME_ADDITIONNELLE_TAUX_1 => 'getSurprimeAddTaux1'),
'getAffSurprime2' => array(
VAL_SURPRIME_ADDITIONNELLE_DUREE_2 => 'getSurprimeAddDuree2',
VAL_SURPRIME_ADDITIONNELLE_TAUX_2 => 'getSurprimeAddTaux2'),
'getAffSurprime3' => array(
VAL_SURPRIME_ADDITIONNELLE_DUREE_3 => 'getSurprimeAddDuree3',
VAL_SURPRIME_ADDITIONNELLE_TAUX_3 => 'getSurprimeAddTaux3'),
'getAffSurprime4' => array(
VAL_SURPRIME_ADDITIONNELLE_DUREE_4 => 'getSurprimeAddDuree4',
VAL_SURPRIME_ADDITIONNELLE_TAUX_4 => 'getSurprimeAddTaux4'),
'getAffSurprime5' => array(
VAL_SURPRIME_ADDITIONNELLE_DUREE_5 => 'getSurprimeAddDuree5',
VAL_SURPRIME_ADDITIONNELLE_TAUX_5 => 'getSurprimeAddTaux5'),
'getAffExclusionsPathos' => array(
VAL_GAR_EXCLUSIONSPATHOS => 'getExclusionsPathologies' ),
'getAffExclusionsSports' => array(
VAL_GAR_EXCLUSIONSSPORTS => 'getExclusionsSports' ),
'getAffExclusionsProfs' => array(
VAL_GAR_EXCLUSIONSPROFS => 'getExclusionsProfessions' ),
'getAffMensualite' => array(
VAL_GAR_MENSUALITE => 'getMensualite' ),
'getAffFranchise' => array(
VAL_GAR_FRANCHISE => 'getAffFranchise' )));
if ($gar->getAffSurmortalite()) {
$tab_gar[$id_g][$idp_idf][VAL_SURMORTALITE ] =
$gar->getTauxSurprime2();
}
if ($gar->getAffSurprime1()) {
$tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_DUREE_1 ] =
$gar->getSurprimeAddDuree1();
$tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_TAUX_1 ] =
$gar->getSurprimeAddTaux1();
}
if ($gar->getAffSurprime2()) {
$tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_DUREE_2 ] =
$gar->getSurprimeAddDuree2();
$tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_TAUX_2 ] =
$gar->getSurprimeAddTaux2();
}
if ($gar->getAffSurprime3()) {
$tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_DUREE_3 ] =
$gar->getSurprimeAddDuree3();
$tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_TAUX_3 ] =
$gar->getSurprimeAddTaux3();
}
if ($gar->getAffSurprime4()) {
$tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_DUREE_4 ] =
$gar->getSurprimeAddDuree4();
$tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_TAUX_4 ] =
$gar->getSurprimeAddTaux4();
}
if ($gar->getAffSurprime5()) {
$tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_DUREE_5 ] =
$gar->getSurprimeAddDuree5();
$tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_TAUX_5 ] =
$gar->getSurprimeAddTaux5();
}
if ($gar->getAffExclusionsPathos()) {
$tab_gar[$id_g][$idp_idf][VAL_GAR_EXCLUSIONSPATHOS ] =
$gar_cm->getExclusionsPathologies();
}
if ($gar->getAffExclusionsSports()) {
$tab_gar[$id_g][$idp_idf][VAL_GAR_EXCLUSIONSSPORTS ] =
$gar_cm->getExclusionsSports();
}
if ($gar->getAffExclusionsProfs()) {
$tab_gar[$id_g][$idp_idf][VAL_GAR_EXCLUSIONSPROFS ] =
$gar_cm->getExclusionsProfessions();
}
if ($gar->getAffMensualite()) {
$tab_gar[$id_g][$idp_idf][VAL_GAR_MENSUALITE ] =
$gar_cm->getMensualite();
}
if ($gar->getAffFranchise()) {
$tab_gar[$id_g][$idp_idf][VAL_GAR_FRANCHISE ] =
$gar_cm->getAffFranchise();
}
Voilà une manière efficace d’accélérer de manière hallucinante les requêtes qui ont, dans le résultat explain
, un extra
qui est : USING filesort
. Cet extra
ralenti énormément la requête.
La solution est très simple : les colonnes de la clause ORDER BY
doivent se retrouver dans le WHERE
: voilà, dans l’exemple qui suit, col1
et col3
qui sont des indexes. S’ils n’apparaissent pas des deux côtés, alors, il y a l’horrible USING filesort
:
mysql> EXPLAIN SELECT * FROM testtab
WHERE col1 > 50000 AND col1 < 150000 ORDER BY col3;
Extra: USING WHERE; USING filesort
mysql> EXPLAIN SELECT * FROM testtab
WHERE col1 > 50000 AND col3 < 20000 ORDER BY col3;
Extra: USING WHERE
mysql> EXPLAIN SELECT * FROM testtab
WHERE col3 < 20000 AND col1 > 50000 ORDER BY col3;
Extra: USING WHERE
mysql> EXPLAIN SELECT * FROM testtab WHERE col3 < 20000
ORDER BY col3;
Extra: USING WHERE
mysql> EXPLAIN SELECT * FROM testtab WHERE col3 < 20000
ORDER BY col1;
Extra: USING WHERE; USING filesort
mysql> EXPLAIN SELECT * FROM testtab WHERE col1 < 20000
ORDER BY col1;
Extra: USING WHERE
mysql> EXPLAIN SELECT * FROM testtab WHERE col1 < 20000
ORDER BY col3;
Extra: USING WHERE; USING filesort