Blog // Exirel.me

Retrouvez tous les articles liés au tag Optimisation via le flux rss dédié à ce tag.

Mélanger redirection, SEO et Webperf...

Par Florian Strzelecki - 01:12 - 07.07.2012

Tags : Web, Bonne pratique, Optimisation, Technique, #trolldredi

Je suis toujours fasciné par la capacité de mes contemporains à chercher la moindre petite bête, le moindre petit détail, là où il n'y a pas besoin de le faire. Ou à, plus précisément, tenter de résoudre un problème qui n'existe pas.

Suite à l'article Réconcilier SEO et WebPerf au niveau des redirections de (sous-)domaines j'ai discuté rapidement sur twitter... mais manifestement mes objections n'ont pas été comprises (mais c'est difficile avec des tweets de débattre de ça).

D'ailleurs, je vous invite à lire les commentaires de l'article, car deux personnes ont déjà soulevé ce que j'ai essayé de dire. Comme le sujet m'intéresse un peu (et que nous sommes vendredi), je vous livre mes réflexions sur le sujet.

Quel est le problème ?

Première question : quel est le problème ? Non mais, vraiment, où est le soucis d'une redirection (de www vers no-www, ou no-www vers www) ?

Si votre site est bien fait - et il l'est, puisque nous sommes des experts, n'est-ce pas ? - vous n'exposez, au monde extérieur, aucun lien incorrect. Les liens de ces immondes boutons collés avec des scripts externes (et qui suivent à la trace vos utilisateurs qui n'ont rien demandé) utilisent le bon nom de domaine, tout comme vos flux rss, vos newsletters, etc.

Bref, de votre côté, tout est bon, et il n'y a donc pas lieu de craindre ni pour votre référencement, ni pour vos performances. Vous assurez grave, bravo !

Considérons ensuite vos utilisateurs, ces gens bizarroïdes qui utilisent "cmd+entrée", et tapent directement le nom de votre site dans leur barre d'adresse. Concrètement, s'ils perdent 75 millisecondes à attendre que leur navigateur trouve la bonne adresse, puis redirigent vers le bon domaine, je pense que ce n'est vraiment pas un soucis. Par contre, si la moindre petite redirection chez vous implique une seconde, je pense que vous avez de sérieux problèmes à résoudre avec votre serveur.

Quant à ceux qui n'indiquent rien (ni TLD, ni sous-domaine), les comportements varient selon les navigateurs et les configurations : avec un label bien placé sous Firefox, cela revient à cliquer sur un favoris, et sans label, à faire une recherche Google (je viens de re-tester à l'instant, histoire d'être sûr).

Dernier petit point que je souhaite soulever : quel est l'importance d'éviter une redirection totalement minoritaire, alors que nous savons tous - vous le savez n'est-ce pas ? - que les scripts des publicités, comme tous les autres chargement de ressources externes et en dehors de votre contrôle, sont bien plus à même d'effectuer des redirections qui pénaliseront le chargement de la page. Pas seulement le chargement de la première requête, mais bel et bien pendant l'ensemble du chargement de la page. C'est à dire, en même temps que le chargement de vos images, de vos scripts et feuilles de style externes. L'échec complet quoi.

Bref, un non-problème. Mais on va dire que c'est quand même un problème, rien que pour parler des solutions.

Quelle est la solution ?

L'internaute moyen ne vois pas où est le problème d'attendre 75 millisecondes de plus dans le chargement de sa page pour une seule et unique redirection. Par contre, il râle lorsque le site affiche plusieurs publicités, chacune faisant perdre plusieurs secondes à sa navigation. Je dis ça, je ne dis rien. Enfin si, je dis quelque chose, je sous-entends même un petit peu que c'est chercher à résoudre un non-problème, mais je l'ai déjà dit plus haut.

Quant aux moteurs d'indexations, ils doivent être considérés comme des utilisateurs comme les autres. Si vous voulez leur parler, vous avez les codes de réponse HTTP (2xx, 3xx, 4xx mais aussi 5xx). Vous avez aussi les robots.txt et les sitemap.xml - mais je ne vais pas vous apprendre le métier.

Si vous cherchez à les cibler plus particulièrement, vous pourrez tout aussi bien avoir de bonnes comme de mauvaises surprises. Les User-Agents n'ont rien de fiable ni de sûr, ils peuvent changer, ne pas être utilisé comme vous le pensé (je suis toujours aussi surpris du fonctionnement de certains User-Agent), et tout un tas d'autres trucs que seuls les robots qui rêvent de moutons électroniques peuvent comprendre.

Dernier point : si vous commencez à avoir des règles conditionnelles de réécriture d'URL pour ça il est peut-être temps de se demander où vous mène toute cette complexité. Oui, je sais, la simplicité, c'est un truc de hipster-bobo-indépendant-hackiviste. Mais quand même, la simplicité, c'est souvent une bonne pratique de WebPerf.

Un A dans YSlow

Il y a un soucis que je me pose avec cette recherche d'une bonne note de WebPerf. Je ne veux pas remettre en cause la note ou sa recherche. Mais par contre, quel est l'intérêt de tester des liens avec le mauvais sous-domaine ?

Parce que, concrètement, si le fonctionnement normal et principal de votre site, c'est sans le sous-domaine (ou avec, vous remplacez mentalement par l'inverse), en dehors d'une éventuelle phase de transition, vous n'avez aucune raison de tester la mauvaise version. Ou alors uniquement pour vérifier que votre serveur sait faire une redirection rapidement et efficacement.

Le reste, ça n'a pas d'importance.

On me souffle à l'oreille qu'un A dans YSlow n'est pas vraiment un bon objectif. Et je vous épargne la citation exacte pour vos chastes oreilles.

Migration vers Django 1.3

Par Florian Strzelecki - 19:41 - 07.03.2012

Tags : Django, Python, Web, Programmation, Développement, Optimisation, Technique

Sur ma liste des choses à faire, il y avait cette migration concrète de mon site&blog vers Django 1.3. Il faut savoir que j'ai développé à l'origine avec la version 1.1, en ajoutant à l'occasion quelques petites choses de Django 1.2 lorsque j'ai mis à jour mon serveur.

Aujourd'hui, mes dernières applications sont développées avec Django 1.3, et il y a quelques petites choses en plus que j'apprécie bien. Je vous propose donc un retour d'expérience, avec un tour d'horizon de ce que j'ai modifié et eu à modifier.

Nommer les urls

Je n'avais pas touché à mon fichier urls.py depuis longtemps, et j'ai donc commencé par là : remettre certains trucs à plat, et rendre le tout plus propre et plus facile à maintenir.

Premier truc : utiliser la fonction url, qui permet entre autre chose de nommer ses urls, ce qui est très pratiques pour la suite, comme, par exemple, ne pas s'embêter à écrire des urls en dur dans les templates.

Exemple de template (avec Django 1.3) :

{% load url from future %}
<p>Lire l'article : <a href="{% url 'entry' entry.url %}">{{entry.title}}</a></p>

Vous noterez l'usage de {% load url from future %}, car le template-tag url a un comportement modifié pour les futures version de Django.

Du côté de la view, cela permet aussi de se simplifier la vie :

def redirect_to_tag(request, section_url):
    """Section now redirect to tag."""
    return redirect('tag', permanent=True, tag_url=section_url)

J'ai simplement nommé l'une de mes urls "tag", et la fonction redirect s'occupe du reste. Si je change la forme des url des tags, je n'aurai pas à changer le code de cette view.

Séparer media et static

Apparu avec Django 1.3, la gestion des fichiers "statiques" a été grandement amélioré par l'intégration de django-staticfiles directement dans le projet Django en tant que django.contrib.staticfiles.

J'ai pu découvrir son fonctionnement avec mon dernier projet (un truc secret pour le moment...), et c'est vraiment très pratique. Le principe ? Au lieu d'avoir un répertoire de médias, intégrant les fichiers de l'application (css, js, etc.) et les fichiers téléversés par les utilisateurs, il y a maintenant deux espaces différents.

Je ne vais pas détailler ici tout ce que j'ai eu à faire mais voici un rapide résumé :

Ensuite, pour lancer la collecte, la commande suivante fonctionne très bien :

python manage.py collectstatic

Au passage, j'ai aussi simplifié un peu ma configuration Apache, mais ça, c'est un autre sujet.

Et d'autres petites choses...

S'il n'y avait que ça, ce serait trop facile. Et bien, en réalité : il n'y avait que ça.

J'avais déjà fait une première passe pour simplifier grandement le code, faire le ménage, et retirer ce qui n'était pas bien fait et/ou bien pensé (avec un code qui a presque deux ans, c'est normal, j'ai beaucoup appris pendant ce temps). Du coup, une migration assez simple, avec, au déploiement, pas un seul soucis.

J'ajoute, au passage, que c'est une bonne expérience, qui permet de revenir sur ce qui a été fait avant, et sur ce que je fais aujourd'hui - et donc, de pouvoir mesurer l'écart.

Dédoublonner un tableau de tableau en php

Par Florian Strzelecki - 16:01 - 30.09.2011

Tags : Documentation, Programmation, PHP, Optimisation, loldev, Technique

Halala... le array_unique est définitivement une fonction trompeuse de php. Pourquoi ? Parce que son mode de dédoublonnage par défaut est SORT_STRING, et pas SORT_REGULAR. D'ailleurs, c'est d'autant plus un problème que ce fut le cas en PHP 5.2.9, puis retour arrière en PHP 5.2.10.

Note : documentation php de array_unique.

Le #loldev du vendredi nous vient donc de cette petite fonction. En voici l'exemple :

$res = array(
        array('id' => 2),
        array('id' => 3907),
        array('id' => 7814),
        array('id' => 2),
    );
$unique = array_unique($res);
var_dump($unique);

// Résultat :
// array(0 => array('id' => 2));

Ce qui est un problème, puisque le but, c'est seulement de virer la deuxième ligne, comme il a été fait dans l'exemple suivant :

$id = array();
foreach ($res as $idRes) {
    $id[] = $idRes['id'];
}
$id = array_values(array_unique($id));

Donc, oui, cela fonctionne et on obtient bien un tableau dédoublonné par la valeur de la clé 'id' de chaque tableau. Heureusement, il y a mieux aujourd'hui.

Ce code provient d'une application pré-5.2.9, où le flag "SORT..." n'existait tout simplement pas. Ce n'est donc pas la faute du pauvre développeur qui a dû trouver à l'époque une solution qui fonctionne ! Je n'aurais pas aimer être à sa place.

Car aujourd'hui, il suffit d'écrire ceci :

$res = array_unique($res, SORT_REGULAR);

Pour dédoublonner le tableau. Simple, efficace. Mais il aura fallu attendre PHP 5.2.9 pour pouvoir le faire !

Remarque : suite à des remarques, voici le pourquoi du comment SORT_STRING pose problème :

Par défaut array_unique transforme en string le contenu de chaque élément du tableau, donc (string) array(...) ça donne "Array". Donc il trouve que le tableau de tableau, c'est un array de 'Array', 'Array', 'Array', ... qui sont donc des éléments identiques, et ne retourne que le premier élément.

Logique, imparable, mais particulièrement pénible.

Ugly code

Par Florian Strzelecki - 01:56 - 28.09.2011

Tags : Framework, Programmation, Bonne pratique, Chaton, Optimisation, Problème, loldev, Technique

Il est parfois difficile de dire d'un code qu'il est bon ou mauvais, qu'il est moche ou élégant. Parfois, les deux se confondent dans un doute profond sur la nature d'une idée, et sur son implémentation.

Beautiful is better than ugly.

Heureusement, parfois, il y a du code php/java/python/javascript/ruby/perl/autre bien sale et c'est très facile à repérer.

Notez l'effort pour ne pas troller toujours sur le même langage.

Moins de code, plus de fonctionnalité

Par Florian Strzelecki - 21:17 - 10.06.2011

Tags : Framework, Programmation, Bonne pratique, Optimisation, Technique

En ce moment, je répète souvent à mes collègues (et à d'autres personnes) la maxime suivante :

Moins de code, plus de fonctionnalité.

C'est devenu mon leitmotiv en ces jours sombres où je dois travailler avec des gens qui n'ont pas encore acquis toutes les compétences nécessaires sur le projet. Et vu mon niveau d'exigence, autant dire que c'est vaguement difficile à gérer pour moi (mais je me soigne).

Pour paraphraser cette pensée, je dirais qu'il ne sert à rien d'écrire beaucoup de lignes de code pour apporter de nombreuses fonctionnalités.

L'important, notamment et surtout dans le cas d'utilisation de framework, c'est de proposer un code simple, facile à étendre, et qui s'intègre bien à son environnement. C'est ma façon à moi de rappeler les principes KISS et DRY : Keep It Simple & Stupid, Don't Repeat Yourself.

Je parle du cas où l'utilisation d'un framework est obligatoire (parce qu'il s'impose de lui-même ou parce qu'il a été arbitrairement imposé), car c'est exactement dans ces moments là qu'il faut rester vigilant.

Dans le cas d'un framework, écrire "moins de code" ne veut pas dire littéralement écrire moins de code, mais plutôt "intégrer parfaitement le moindre code dans le contexte du framework".

Si le framework impose d'écrire une classe, ou plusieurs, pour écrire un "plugin", alors il vaut mieux le faire, plutôt que d'écrire quelque part codé en dur dans le code, la modification voulue.

C'est peut-être paradoxal, mais cela fonctionne mieux. C'est peut-être frustrant, mais cela évite bien d'autres frustrations.

Croyez-moi, il vaut mieux que tout fonctionne toujours parfaitement avec le framework, que tout fonctionne maintenant comme vous le voulez contre le framework.

Parce que le framework lui, il a déjà écrit beaucoup, beaucoup, beaucoup de lignes de code.

Boucle et SQL (et ORM) : la petite erreur à éviter

Par Florian Strzelecki - 18:51 - 11.04.2011

Tags : Programmation, Bonne pratique, PHP, Optimisation, ORM, SQL, Technique

Petite précaution avant d'entamer la lecture de cet article : il est technique, certes, mais ne concerne pas spécifiquement ni symfony ni doctrine. Le sujet de l'article est un problème technique très concret, qui se retrouve dans tous les langages, et avec n'importe quelle base de données.

En lisant le livre "Pratical symfony", plus spécifiquement le chapitre 6, je suis tombé sur un cas très classique : afficher une liste d'élément par catégorie, comme dans l'exemple qui suit.

L'approche ici - mais j'ai déjà vu ça ailleurs très souvent - est de récupérer la liste des catégories, puis, pour chaque catégorie, de récupérer la liste des offres de ladite catégorie.

Sauf qu'il y a un problème : voyez-vous lequel ?