Accueil > Blog-notes > Ma participation au Webperf-Contest 2010

Ma participation au Webperf-Contest 2010

J’ai participé au Webperf-Contest 2010 organisé par zeroload. Je reviens dans le détail sur cette expérience qui fut enrichissante et énergivore.

Le concours

Ainsi qu’exposé sur son site le but de ce concours de Web performance était d’optimiser une page web existante et essayer d’obtenir le meilleur résultat possible dans 3 catégories (score selon http://www.yottaa.com, « onload » et « start render » calculés à l’aide de http://www.webpagetest.org, et plus petit nombre de requêtes et poids du site)

Chaque participant disposait d’un espace FTP alloué à son inscription, et devait y uploader le résultat de son optimisation pour qu’elle soit ensuite évalué par un jury.

Le concours s’est déroulé du 25 octobre au 30 novembre 2010.

Ma participation

Je me suis inscrit au concours en partie par jeu (j’aime assez les défis et autres casse-têtes), en partie car c’était une bonne occasion de me mettre à niveau, d’approfondir des sujets techniques autour du WPO que je n’avais pas encore pris le temps de creuser, et enfin de m’évaluer par rapport aux autres sur ce sujet.

La page à optimiser était tirée du site de la Fnac, et plus particulièrement de la page enfant, figée au moment du concours.

La page à optimiser

Après un premier examen rapide du contenu de la page, il est vite apparu que l’optimisation allait faire appel à un large spectre de compétences.

Dans sa forme, la page est en effet assez typique de ces gros sites qui ont une histoire, que l’on retrouve comme autant de couches sédimentées. Chaque intervenant qui passe dessus rajoute ses évolutions, corrections, modifications, se superposant aux précédentes que l’on se garde bien de toucher de peur que cela ne casse une autre partie du site.

Avoir une vision globale d’un gros site comme celui de la Fnac est en effet souvent bien difficile, et il est du coup presque impossible de nettoyer l’existant avant toute modification. Tout cela entraine une lente dérive vers toujours plus de composants JS, plus de directives CSS, une construction HTML de la page qui s’alourdit... et un site qui manque de réactivité et de vélocité.

Il n’y avait qu’à regarder la cascade de chargement initiale pour achever de s’en convaincre.

Waterfall de la page initiale

De la méthode, du travail... et du temps !

De fait, le temps nécessaire à passer sur le concours pour parvenir à une copie d’un très bon niveau s’est avéré complètement disproportionné par rapport à l’espoir de gain matériel (dans le meilleur des cas un iPad).

Certains ont préféré arrêter les frais après une journée de travail, sur la foi d’une logique purement financière.

En ce qui me concerne, j’ai un rapport à mon activité qui n’est pas guidé par ce genre de logique, et je suis capable de passer beaucoup de temps sur un sujet sans espoir de rémunération, simplement parce que cela me plaît. C’est le genre de choses pour lesquelles j’apprécie mon statut d’indépendant : avant tout pouvoir faire ce qui me plaît [1]

Je me suis donc attelé au travail d’arrache-pied, en prenant les problèmes techniques un par un, sans chercher à arriver tout de suite à un résultat.

Une des premières choses que j’ai faites est de versionner mon projet. C’est une déformation que j’ai héritée de ma contribution à un projet libre [2] : je ne sais plus travailler sans un outil de gestion de version. Même seul, c’est tout simplement indispensable, pour le confort que cela apporte [3].

J’ai ici choisi d’utiliser GIT pour sa simplicité de déploiement (pas besoin de dépôt distant), et avec l’idée d’envoyer tout le projet sur GitHub une fois le concours terminé.

Mon optimisation

Je ne vais pas reprendre ici mon travail dans un ordre chronologique, cela serait bien trop long, et les curieux pourront toujours s’en référer à mon historique. Je préfère plutôt faire une synthèse de toutes mes optimisations.

Pour ceux qui veulent voir tout de suite le résultat, mon optimisation est encore visible en ligne à ce jour.

Rendu

Le rendu est identique à l’origine dans les navigateurs modernes hormis :

  • les coins ronds ne sont pas rendus dans les navigateurs ne supportant pas border-radius,
    et se dégradent en coins carrés
  • les header des boites de la colonne de droite qui sont homogénéisées
    avec les boites en colonne centrale

Pour tous les header de boite, j’ai remplacé le système
d’images de background par un jeu d’aplat en pur CSS, ce qui ne nécessite aucune ressource externe.

J’ai nettoyé le layout de la page initialement en table, puis remplacé par le layout tiré de http://blog.html.it/layoutgala/ qui permet d’envoyer le contenu principal avant les colonnes latérales (les id de blocs de la page ont été conservés).

Header de la page

L’auto-complétion sur le champ de recherche n’est activée qu’au focus sur le champ, ce qui permet d’économiser le chargement de ce script la plupart du temps.

Le menu déroulant à onglets n’étant navigable qu’en présence de javascript, j’ai pris le parti de n’insérer dans le HTML du document statique que la partie visibles des onglets.

L’ensemble des parties déroulantes, qui représente 8Ko gzippé, est chargé de manière asynchrone par une requête AJAX, et n’est injecté dans le DOM par morceau que lorsque cela est nécessaire.

Pour l’affichage des onglets, j’ai gardé des images car c’est à mon avis la seule solution industrielle pour respecter la police de la maquette graphique et être robuste vis a vis de l’agrandissement du texte dans le navigateur.

En revanche j’ai mutualisé l’affichage onglet au survol/onglet actif qui utilisent tous deux du texte noir (le rendu n’est ici pas parfait car il aurait fallu régénérer les textes sans background, ce que je n’ai pu faire faute de disposer de la bonne police, et je me suis contenté de découper les textes dans les images disponibles), et j’ai fait en sorte que le menu soit utilisable même si on navigue sans image.

Les images d’illustration dans le « megamenu » dépliant sont rassemblées en un sprite unique qui n’est chargé qu’au premier affichage, par positionnement de la directive CSS en javascript.

Contenu central

Le diaporama central était constitué d’images sans alternatives. J’ai remplacé cette image par un texte+une image de background en superposition. Seule la première image est référencée au chargement
de la page, les autres images ne le sont que lors de leur affichage (via javascript), ce qui permet un
chargement différé.

Pour accélérer le rendu initial dela page, j’ai aussi remplacé la première image du diaporama par une première image JPG de basse qualité remplacé ensuite par l’image de qualité initiale (PNG dans le cas présent) lorsque le reste de la page est chargé. L’image de basse qualité n’est visible que l’espace de quelques instants, et le temps que l’œil du visiteur se fixe réellement dessus elle est remplacée par sa version de bonne qualité. Cela permet d’avoir un rendu initial plus rapide, qui est ensuite amélioré.

Les images de la page ne véhiculant pas d’information et utilisées comme illustration sont toutes référencées en image de background et regroupées en sprites par ensemble logique cohérent (automatisable en production) :

  • illustrations dans le menu déroulant, enrichies d’une alternative texte lorsqu’aucune image n’est chargée
  • illustrations des héros préférés, rassemblées dans le même lien que le texte associé, afin que le survol de l’un ou l’autre suffise [4]
  • illustrations des univers en colonne de droite

En revanche, les images des produits constituent une information essentielle de la page et nécessaire à la vente (au même titre que le nom du produit ou son prix).
Il m’a donc semblé essentiel que ces images soient présentes aussi bien en l’absence de styles que de javascript. J’ai donc choisi de les conserver en image inline, mais j’ai utilisé du lazy-loading dessus (voir le paragraphe à ce sujet pour ce qui concerne l’accessibilité des images sans javascript).

Colonne de droite

La colonne de droite est chargée par une requête asynchrone. Au chargement de la page, elle est visuellement remplacée par un cadre bloc légèrement grisé visible en cas de rendu lent (IE7 ou connexion lente)

Le GIF animé utilisé en bannière publicitaire interne est lourd à charger.
Pour ne pas retarder le rendu complet de la page, il est initialement remplacé par un PNG statique qui ne reprend que la première image. Le GIF animé est ensuite chargé dynamiquement en lieu et place de ce PNG statique pour lancer
l’animation lorsque la page est achevée de charger.

Les images d’illustrations de chaque cadre sont dans un sprite unique qui peut être généré dynamiquement. Comme ces boites sont en général sous la ligne de
flottaison et non visible au chargement de la page, la directive background-image est insérée en javascript asynchrone pour ne pas retarder le onload, uniquement lorsque le premier bloc est au dessus de la ligne
de flottaison (utilisation du script https://github.com/Cerdic/webperf-contest-2010/blob/master/js/sources/jquery.lazyload.js)

Pied de page

Le pied de page non initialement visible en général est chargé par une requête AJAX asynchrone.

L’iframe est conservée, conformément au règlement, mais son attribut src est initialement vide. Elle est chargée de manière aysnchrone par injection du src en javascript lorsque le pied de page devient visible (lazy loading)

Techniques&outils utilisées

Optimisation des images

Pour l’optimisation des images j’ai utilisé le logiciel ImageOptim, qui est en fait une simple interface OSX vers les outils les plus couramment utilisés (OptiPNG, PngCrush, JpegOptim).

Pour les images JPG, j’ai essayé d’augmenter le taux de compression jusqu’à une limite visuellement acceptable. Cette optimisation est ici la plus discutable de ce que j’ai pu faire, car mon niveau d’acceptabilité est peut-être sensiblement différent de ce qu’il serait possible de faire avec un DA dans le dos.

Le vrai problème est de trouver le compromis entre le poids des images (qui peut faire gagner des clients par la rapidité du site) et le rendu (qui peut faire perdre des clients si il n’est pas assez qualitatif). Difficile de trouver ou placer la barre, et j’ai donc considéré que je pouvais diminuer le poids des images tant que je n’étais pas choqué par le rendu en tant que simple client (un DA n’étant de ce point de vue pas représentatif non plus !).

Chargement asynchrone de blocs de page

J’utilise une technique inspirée des BigPipe de Facebook
et déjà automatisée dans le cadre de SPIP.

Elle consiste à faire assembler certains blocs de la page en javascript par le client au lieu de le faire côté serveur.

Le chargement asynchrone se fait par une requête XHR lancée aussitôt que possible.
Le HTML est injecté dans la page lorsqu’il arrive. Ici le HTML ne contient pas de script inline, et on fait tout cela en javascript natif sans jQuery (pour ne pas devoir attendre le chargement de ce script).

Ici, IE7 étant une cible a prendre en compte, j’ai limité au nombre de 2 les blocs chargés en asynchrone car ceux ci doivent être chargés sur le même domaine que la page principale, et IE7 ne peut ouvrir que deux connexions simultanées par domaine.

L’accessibilité au contenu lorsque le visiteur ne dispose pas de javascript se fait par une directive <noscript> avec une directive

<meta http-equiv="refresh" content="1;url=index.st.html">

qui redirige
le visiteur vers une version de la page assemblée côté serveur. Dans un contexte de production, on poserait un cookie au visiteur la première fois que cela arrive, et on ne lui servirait plus que des pages complètes.

De même, les robots connus sont repérés côté serveur par leur user-agent et sont directement servis par la version complète. Les robots non connus suivent en principe la directive meta refresh. Au pire, il leur manque ici les deux blocs (colonne de droite et pied de page) qui ne sont pas cruciaux pour le référencement (en particulier si l’on sert un sitemap).

Dans cette approche, seul l’ossature de la page change de forme entre les deux versions (techniquement c’est le mécanisme d’inclusion qui est traduit de deux façons différentes possibles)

Ici, la redirection se fait sur index.st.html, qui est une version complète même sans javascript [5].

Lazy Loading

Le lazy-loading consiste à ne charger certains éléments de la page que lorsqu’ils deviennent visibles par l’internaute.

A partir du moment ou les visiteurs sans javascript étaient redirigés vers une page complète, j’ai considéré acceptable de faire reposer l’affichage de certains contenus sur javascript dans la version optimisée.

J’utilise donc du lazy-loading sur 3 familles d’éléments :

  • sur les images de produit du contenu principal de la page.
    les balises <img> de la page sont dépourvues d’attribut src mais disposent à la place d’un attribut original.
    Le script jquery.lazyload.js est utilisé pour charger dynamiquement les images qui apparaissent dans la fenêtre du visiteur lorsque celui-ci scrolle. Ceci se fait par recopie de
    l’attribut original sur l’attribut src.
    Dans la version alternative, les images sont référencées normalement
    dans la page et sont toutes chargées normalement.
  • sur les background-image de décoration des boites en colonne de droite. Ces décorations ont été passées en sprite et du coup le lazy load est ici géré manuellement, en utilisant toute fois les fonctions de detection du script lazyload [6]
  • sur l’iframe : celle-ci étant en pied de page, je n’injecte son attribut src que lorsqu’elle est
    susceptible de devenir visible.

CSS

La feuille de style principale unique initiale a été découpée en unités logiques, chacune dans une feuille,
toutes rangées dans le dossier css/sources/.
Ensuite, je créé une feuille combinée par SSI qui n’inclue que les feuilles nécessaires
à la page.

J’ai donc procédé par sélection de module fonctionnel CSS comme on pourrait le faire
en contexte de production, mais j’ai exclu de nettoyer chaque fichier CSS de tous les sélecteurs inutiles à la page du concours.
Par exemple, j’inclue la feuille entière qui style toutes les boites du site même si on n’en utilise ici que quelques variantes, car c’est ce qu’on pourrait faire en production.

J’ai testé la séparation des CSS en deux lots core+complements dont le premier serait inséré inline mais cela n’améliorait pas dans mon cas le début de rendu dans IE7 (cela améliorait le « start render » apparent mesuré, mais pas en pratique le début réel du rendu tel qu’on peut le voir avec capture vidéo).

J’en suis donc resté à une CSS unique, minifiée par CSSTidy [7]

La feuille minifiée est https://github.com/Cerdic/webperf-contest-2010/blob/master/css/style.minified.css et correspond à https://github.com/Cerdic/webperf-contest-2010/blob/master/css/sources/style.combined.css

Javascript

Les javascript inline figurant initialement dans la page ont été déportés dans des fichiers externes, par fonctionnalité principale.
Dans la même approche que pour les CSS, seuls les scripts utiles à la page ont été inclus dans la page. En revanche, dans les fonctions d’alignement de bloc, seules celles utiles sur la page ont été ici conservées.

Les javascript ont été concaténés par SSI, et minifiés à l’aide du Google Closure Compiler.

J’ai travaillé initialement avec un unique script qui chargeait tout en une fois. Mais la taille de ce fichier en a fait le chemin critique pour réduire le « onload » de la page, et je suis donc passé à deux fichiers :

Pour cela, il a fallu gérer le chargement parallèle et asynchrone de ces deux fichiers, et que cela fonctionne dans tous les navigateurs. J’ai donc développé un chargeur jQuery asynchrone pour cela [8]

Le placement des CSS et JS dans la page est optimisé afin qu’ils soient chargés le plus tôt possible sans bloquer aucun des chargements qui les suivent, soit :

  • d’abord le chargement de jQuery par une directive <script> avec un attribut defer
  • puis le script inline jQl et l’appel du chargement asynchrone du second script
  • puis la feuille de style minifiée par une directive <link> traditionnelle

JSON

La page contenait initialement 16 requêtes JSON pour charger les informations de disponibilité et prix des articles. Une des premières choses que j’ai faite est de mutualiser ces requêtes en une seule, à laquelle on passe en argument les prid recherchés, sous
forme de tableau.

Le serveur d’origine de la fnac n’étant pas en mesure de servir cela, on mime ici à l’aide d’un fichier javascript statique qui renvoit en JSON toutes les infos demandées. Dans la réalité, il faudrait simplement modifier le script serveur de la Fnac pour lui permettre de répondre à une requête multiple, ce qui ne pose pas de difficulté particulière [9]

HTML

Le HTML a été minifié par suppression des espaces redondants et commentaires. J’ai utilisé pour cela de simples expressions régulières.

Cookies

Par défaut, le marqueur de statistiques pose des cookies sur le domaine .webperf-contest.com et contamine tous les sous domaine s1/s2/s3.

J’ai donc patché le marqueur de statistique pour qu’il pose ses cookies sur entries.webperf-contest.com

Parallélisation et Cookie-free domains

J’ai utilisé les sous sdomaines s1/s2/s3 au maximum pour charger les ressources statiques (images et CSS).

En revanche les javascript sont servis sur le domaine principal entries.webperf-contest.com car cela permet une meilleure parallélisation (les connexions sur les autres domaines sont toutes chargées a bloc dans IE7) et un des scripts chargé par une requête XHR ne peut provenir d’un autre domaine que celui de la page principale.

Les morceaux de page asynchrones sont aussi chargés par une requête XHR, et donc sur le domaine principal. Comme il s’agit de HTML qui pourrait éventuellement utiliser des cookies, c’est aussi logique de faire comme cela.

Le JSON du marketplace est également chargé sur le domaine principal.

.htaccess

Le fichier .htaccess est utilisé pour

  • forcer la compression GZIP (mode deflate) sur tous les contenus pertinents (HTML, JS, CSS) mais pas sur les images.
  • forcer des expire lointains sur les fichier statiques (image, CSS, JS).
    En situation de production cela s’accompagnerait d’un timestamp sur les urls pour les versionner et forcer la mise à jour en cas de modification
  • bloquer les cookies sur les fichiers images (précaution en général inutile, mais je me suis battu sur ce point avec YOTTAA avant de comprendre que c’était un bug de sa part, corrigé depuis)

Résultat & Bilan

Le temps de chargement total de la page a été fortement réduit

Waterfall de la page après optimisation

Le « onload » a été divisé par 10 (il est passé de 11.893s à 1.2s environ), le « start render » divisé par 2, le nombre de requêtes divisé par 5.

Mais le plus important est que tout cela a été obtenu uniquement avec des techniques déployables en production. Il y aurait évidemment encore du travail pour intégrer ces optimisations au site complet de la Fnac (en prenant en compte l’aspect dynamique de certains contenus) mais aucune des solutions retenues n’est irréaliste ni très compliquée à mettre en œuvre.

L’organisation du concours a été impeccable. Mes questions particulières concernant des points de règlement ont toujours reçu une réponse rapide.

Le niveau du concours a été assez relevé [10], et l’affichage en live du classement a été un facteur d’émulation certain qui a conduit à pousser chacun vers toujours plus d’effort d’optimisation.

D’un point de vue personnel, ce concours est déjà une réussite :

  • j’ai largement perfectionné mes connaissances concernant la synchronicité des chargements des composants d’une page, passant de nombreuses heures à relire Steve Souders dans le texte ;
  • j’ai repris et mis a jour le projet libre CSSTidy ;
  • j’ai lancé un nouveau projet de chargeur asynchrone pour jQuery ;
  • j’ai commencé à intégrer ces outils et connaissances pour améliorer l’automatisation de l’optimisation des pages dans SPIP (regardez donc le source de ce site) ;
  • je pense avoir démontré un certain niveau de savoir et savoir faire, qui ne peut avoir que des retombées professionnelles positives, même si ce n’est que très indirectement.

La seule petite critique que je pourrais faire sur le concours, avec le recul, concerne sa durée. Il est louable de le faire courir sur 5 semaines pour permettre à tout un chacun de participer compte tenu de ses disponibilités.

Mais en pratique, il subsistera toujours une distorsion entre ceux qui, comme moi, ont pu y consacrer plus que leurs soirées et/ou week-end, et ceux qui ont un temps limité. A moins d’une semaine de la fin du concours, il était clair que ceux qui n’avaient pas encore vraiment commencé ne pourraient jamais rejoindre le peloton de tête compte tenu de l’effort réalisé par ceux-ci. Aussi j’aurais tendance à penser qu’une durée plus réduite permettrait un effort plus ponctuel, et plus supportable aussi.

Mais hormis ce petit détail, je ne retiens que du bon : dans la mesure où je me suis amusé, cela valait le temps que j’y ai passé !

Il ne reste plus maintenant qu’à attendre la publication des résultats, et j’avoue que je suis curieux de voir les techniques utilisées par les autres concurrents !

— 7 décembre 2010

Documents joints

Notes

[1même si il ne faut pas oublier non plus d’avoir une activité rémunérée suffisante en moyenne !...

[2SPIP pour ne pas le nommer. Ah mince, c’est fait...

[3possibilité de revenir en arrière, de brancher, de retracer ses modifications, en sus de la sauvegarde en ligne lorsqu’on utilise un dépôt distant

[4permet également une amélioration de l’accessibilité par suppression des liens successifs redondants qui compliquent inutilement la navigation avec revue d’écran

[5c’est en fait une version moins avancée
de mon l’optimisation, et elle est également fonctionnelle avec javascript

[6L’utilisation d’une sprite n’a du coup ici que peu d’intérêt en performance dans ce cas, sauf à permettre de charger toutes les 4 images d’un coup. Mais je n’ai pas voulu prendre le temps de revenir à des images inline...

[7Ce dernier n’est plus maintenu mais la dernière version distribuée contenait quelques bugs. J’ai donc
repris le code sur https://github.com/Cerdic/CSSTidy,
corrigé les tickets ouverts sur sourceforge, complété les tests etc...

[8Malheureusement, en remettant au propre mon projet pour la livraison finale, j’ai livré par mégarde une version dans laquelle jQuery ne démarrait pas dans Safari, ce que j’ai corrigé par https://github.com/Cerdic/jQl/commit/fa904f2b946002cf0137887be8cf0f403650f3a8

[9Même si côté serveur le source s’avérait trop compliqué pour être corrigé simplement, il serait possible d’y faire de multiples appels du script existant et d’agréger en une réponse unique. C’est moins optimisé, mais cela serait toujours plus rapide que de réaliser N requêtes par le client distant.

[10il me semble, autant que je puisse en juger

Vos commentaires

  • Le 7 décembre 2010 à 12:10, par Pixelastic En réponse à : Ma participation au Webperf-Contest 2010

    Très interessant comme debrief, il faudrait que je fasse de même.

    Mettre des versions de basses qualités des images avant de les remplacer par les versions complètes est une très bonne idée, ça me rappelle le principe des « Level of Details » utilisé en 3D/Jeux vidéos.

    Idem pour servir une version non-Javascript (ou plutot : servir une version Javascript only sur laquelle tu peux t’éclater à coup de lazyload sans avoir peur de gacher l’experience de tes visiteurs sans JS).

    Par contre la façon de charger la page par blocs (à la Facebook comme tu l’indiquais) je n’ai jamais fait, je m’interroge sur la complexité coté serveur pour automatiser une telle technique ?

    Charger le JSON depuis le domaine principal (car les cookies y sont sans doute nécessaire), j’avais oublié ça, tu a raison de le préciser.

    Sinon, il y a le fait de charger le contenu du menu principal en AJAX qui me semble « dangereux ». Bien qu’il ne soit accessible qu’avec JS comme tu l’indiques, en faisant ainsi tu le rends aussi complétement invisible aux moteurs de recherche. C’est un choix que je n’ai pas osé faire dans ma participation.

    En tout cas, c’était très instructif. Merci aussi d’avoir repris CSSTidy, je participerai à son amélioration.

  • Le 7 décembre 2010 à 12:29, par Touffies En réponse à : Ma participation au Webperf-Contest 2010

    Merci beaucoup pour ce post... Je suis impressionné et émerveillé par le nombre de techniques possible pour optimiser une page. J’ai également hate de voir les résultats.

    Ce concours m’a vraiment permis de re-découvrir le web :)

    Bonne chance a toi.

  • Le 7 décembre 2010 à 13:44, par ? En réponse à : Ma participation au Webperf-Contest 2010

    Merci pour ce post, il y a des techniques intéressantes que vous avez utilisé, mais malheureusement les aspects SEO sont pas pris en compte.

  • Le 7 décembre 2010 à 13:51, par Cedric En réponse à : Ma participation au Webperf-Contest 2010

    A quels aspects SEO pensez-vous ? vis à vis de quelles techniques ? Je ne suis pas entré ici dans le détail de chaque technique, mais on peut le faire (et j’ai essayé de renvoyer vers des articles plus complet quand c’était possible).

  • Le 7 décembre 2010 à 16:25, par ? En réponse à : Ma participation au Webperf-Contest 2010

    je parle du menu et du iframe que vous avez sauté en les chargeant en ajax, c’est pas un jugement, ce n’est que mon avis :)

  • Le 7 décembre 2010 à 17:47, par Cedric En réponse à : Ma participation au Webperf-Contest 2010

    Les gros menu déroulants ne font que proposer des liens directs redondants avec la colonne de navigation présente sur chaque page accessible depuis l’onglet visible. Ainsi la navigation des robots d’indexation n’est pas entravée de ce point de vue.

    A contrario, en enlevant toute cette partie de HTML (8ko gzippé), j’ai fait fortement remonter le vrai contenu de la page dans le source, et cela le rend beaucoup plus accessible aux robots d’indexation, et lui donne plus de poids. C’est donc un plus pour le référencement, à mon sens.

    En ce qui concerne l’iframe, il faut savoir que lorsque celle-ci n’est pas chargée, elle est remplacée par un lien alternatif vers le contenu qu’elle propose, ce qui permet là aussi aux robots d’indexation de retrouver leur contenu. Proposer du contenu dans une iframe est de toute façon un non sens, et elle n’a été conservée ici que pour respecter le règle du concours. Dans la vie réelle, on ferait tout pour s’en débarasser au profit d’une inclusion côté serveur.

  • Le 7 décembre 2010 à 18:04, par Vieuxsteak En réponse à : Ma participation au Webperf-Contest 2010

    Un grand merci pour ce post, vraiment très intéressant (je pense que c’est une des premières fois que je lis un post en bonne partie et avec grand intérêt).

    Je vais pouvoir mettre en pratique quelques techniques fort intéressantes !

    Encore merci.

  • Le 8 décembre 2010 à 00:53, par ? En réponse à : Ma participation au Webperf-Contest 2010

    merci Cédric pour les explications, et bonne chance pour la suite

  • Le 8 décembre 2010 à 23:42, par tetue En réponse à : Ma participation au Webperf-Contest 2010

    Aaaah, le lazy loading et son détestable effet d’affichage des images à retardement ! Cet effet ne me semble pas gênant ici, alors que je le trouve insupportable sur d’autres sites et blogs (comme owni.fr). Sans doute son usage est-il plus adapté à des visuels de catalogue qu’à des contenus éditoriaux illustratifs. Intéressant.

    Petite considération annexe : je ne suis pas d’accord avec ce que tu dis du statut d’indépendant, qui laisse entendre qu’on y ferait ce qui plaît sans se soucier de rentabiliser... C’est faux : indé et salarié ont pareillement besoin de bouffer ! On peut simplement considérer que tu as utilisé l’intégralité de ton temps de loisir à ce concours.

    Merci d’avoir documenté ta participation.

  • Le 8 décembre 2010 à 23:55, par Cedric En réponse à : Ma participation au Webperf-Contest 2010

    En ce qui concerne le lazy-loading, il y a plusieurs choses à savoir :

    • le script généralement utilisé (sur owni que tu cites, mais d’autres media l’utilisent aussi), ne fonctionne plus correctement sur les navigateurs récents. Le résultat est donc que les images sont chargées dès le départ, puis enlevées, puis rechargées. On a donc au final tous les inconvénients cumulés.
    • il y a des variantes de réglages qui permettent de le rendre plus discret (notamment un seuil par rapport à la ligne de flottaison, pour anticiper le scrolling)
    • il est probablement plus adapté à de petites images qu’à de grandes dont l’absence se remarque plus nettement.

    En ce qui concerne le statut d’indépendant, il donne la liberté de placer le curseur rentabilité/intérêt comme on le veut à un instant donné, et surtout d’organiser son temps de manière beaucoup plus souple. Cela m’a donc permis de consacrer des journées complètes sur le concours.

    Tu as toutefois raison de rappeler que cela ne peut être permanent, évidemment, et qu’en moyenne on ne peut négliger totalement la rentabilité du temps.

  • Le 14 décembre 2010 à 11:35, par Marcimat En réponse à : Ma participation au Webperf-Contest 2010

    Bravo en tout cas... car ces recherches semblent avoir bien porté leurs fruits !
    « Fastest Onload & start render times » avec tout ça... Chapeau :)

  • Le 21 décembre 2010 à 08:57, par Loiseau2nuit En réponse à : Ma participation au Webperf-Contest 2010

    Bravo Cédric, je crois que la communauté SPIP te reconnait bien là :-D (Ah mince, moi aussi je l’ai nommé :-X )

    Pour le reste, c’était quelque peu osé en effet, de shunter le menu d’un point de vue SEO mais l’aternative proposée me parait à priori cohérente. Maintenant à voir dans la pratique sur un vrai site en prod.

    Puis à voir la page à optimiser, c’était certainement plus justifié dans ce cadre que pour d’autres site minimisant au max le nombre de liens (pour mieux controller la répartition du « jus ») et pour lequel charger conditionellement un menu est pour le coup un non-sens.

    Enfin bref, en tout cas merci pour les petits outils mentionnés par ce post, me voila pleins de nouveaux joujoux à tester :-)

  • Le 30 janvier 2011 à 00:17, par rivsc En réponse à : Ma participation au Webperf-Contest 2010

    Super article.

    Par contre ou m’avait persuadé que grouper les css et les js économisait des requêtes et donc c’était plus performant. En fait l’inverse est mieux à cause de la parallélisation des téléchargements par le navigateur. J’ai bien compris ?

  • Le 30 janvier 2011 à 13:41, par Cedric En réponse à : Ma participation au Webperf-Contest 2010

    Non, la règle générale de regrouper tous les js en un seul fichier est bonne et c’est bien ça qu’il faut avoir pour objectif.

    Mais dans le cas précis du concours, comme tout le reste de la page était optimisé et se chargeait rapidement, le chargement du fichier js unique est devenu limitant, et j’ai donc du le découper en deux. Cela dit c’est un cas extrême et le but était ici de gagner les dernières dizaines de millisecondes.

    Je pense que dans un contexte de production j’aurai choisi de garder un seul fichier, car c’est tout de même plus robuste et maintenable, et c’était déjà très performant.

  • Le 5 février 2011 à 00:58, par rivsc En réponse à : Ma participation au Webperf-Contest 2010

    Merci pour la précision !

  • Le 20 février 2011 à 12:58, par klelugi En réponse à : Ma participation au Webperf-Contest 2010

    Tout d’abord bravo pour toutes ces optimisations, c’est un article très instructif et rempli de bonnes pratiques (voir que des bonnes pratiques).

    L’appel aux portions du menu via AJAX n’est en rien un facteur bloquant pour le SEO.

    L’utilisation de ce genre de techniques est d’ailleurs conseillée pour des sites dont le nombre de pages est aussi important que celui de la FNAC, cela permet de développer la technique de « siloing », où les informations sont disponibles par grandes catégories sur un site et ainsi de favoriser une meilleure contextualité au sein des pages car les seuls liens présents dans la page sont ceux qui concernent directement la thématique ciblé par la page en cours de lecture.

    - La mise en avant du contenu en premier via le gabarit proposé par Layout Gala,
    - L’appel du footer qui contient des liens pas essentiels au SEO via AJAX,
    - Et tout le travail d’optimisation des temps de chargement de la page

    sont autant de facteurs positifs pour améliorer la capacité de positionnement d’une page, il n’y a donc ici aucuns facteurs bloquants au SEO à mon sens,

    Bravo !

Répondre à cet article

Qui êtes-vous ?

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici
  • Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Suivre les commentaires : RSS 2.0 | Atom