SlideShare une entreprise Scribd logo
1  sur  43
Télécharger pour lire hors ligne
Ma participation au WebPerf Contest 2010




Cédric Morin / yterium // WebPerf 16 janvier 2012   1
Cédric Morin

Développeur freelance

http://www.yterium.net/
https://github.com/Cerdic/
@GusLeLapin




Cédric Morin / yterium // WebPerf 16 janvier 2012   2
Le concours

http://webperf-contest.com/index-fr.html




Cédric Morin / yterium // WebPerf 16 janvier 2012   3
Règles

• résultat graphique doit être «strictement»
  identique à l’original
• optimisations conservent les fonctionnalités de
  la page web originale.
     • Le champs recherche et son autocomplétion
     • Le défilement doux lorsqu'on clique sur la
       flèche à droite de "mon panier"
     • Slider central avec changement automatique
       et manuel des images
     • Les menus du haut et sous menus au survol
     • Les indications "x produits trouvés" qui sont
       récupérées en ajax
     • Le système de tracking doit fonctionner
       (s_code)
     • Toutes autres fonctionnalités ...

Cédric Morin / yterium // WebPerf 16 janvier 2012      4
Règles

• L'expérience utilisateur doit être préservée (et vous pouvez
  l'améliorer), par exemple :
     • Une fois la page chargée, la page doit être aussi fonctionnelle
       qu'à l'origine

     • L'accessibilité ne doit pas être sacrifiée (vous pouvez même
       l'améliorer)

     • Les optimisations pour référencement doivent être préservées
       (vous pouvez également les améliorer)

• La règle principale est :
     • agissez comme si c'était votre site ou votre client. Tout
       sacrifier pour la performance web ne sert à rien.

Cédric Morin / yterium // WebPerf 16 janvier 2012                        5
La page à optimiser

• http://www.webpagetest.org/result/
  101207_6ed820576ae1663a7bf929e648e2dd34/




Cédric Morin / yterium // WebPerf 16 janvier 2012   6
Cédric Morin / yterium // WebPerf 16 janvier 2012   7
Avant

• Des indicateurs macroscopiques PageSpeed
  plutôt corrects


• 115 requêtes http pour charger toute la
  page pour 592ko


• 2.44s / 11.03s / 17.2s




Cédric Morin / yterium // WebPerf 16 janvier 2012   8
Avant

•Répartis sur 5 canaux :
     •2 sur le domaine de la page du concours
     •1 sur metrics.fnac.com pour le marqueur de stats
     •2 sur www4.fnac.com, qui concernent des requêtes
      ajax




Cédric Morin / yterium // WebPerf 16 janvier 2012        9
Techniques et outils utilisés




Cédric Morin / yterium // WebPerf 16 janvier 2012   10
Versionner

•Tout versionner dès le début

•Tout est disponible sous
 https://github.com/Cerdic/webperf-contest-2010




Cédric Morin / yterium // WebPerf 16 janvier 2012   11
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) pour optimiser les «Repeated view»
       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é postérieurement au concours)

Cédric Morin / yterium // WebPerf 16 janvier 2012                     12
Optimisation des images

• Optimisation systématique via ImageOptim
     • interface OSX vers les outils les plus usuels (OptiPNG, PngCrush, JpegOptim)
       http://imageoptim.pornel.net/

• Pour les images JPG
     • compromis poids/qualité toujours discutable

     • mauvaise qualité peut faire perdre des clients, mais poids aussi (par ralentissement
       des pages)

     • je me suis fixé le critère d’apparence ‘acceptable en tant que client’, serait sûrement
       critiqué par un oeil expert (mais non représentatif non plus)

• Preloading
     • en début de <body>, pour démarrer au plus vite le chargement des images et
       maitriser l’ordre




Cédric Morin / yterium // WebPerf 16 janvier 2012                                               13
Sprites

•regrouper des images qui ne portent pas d’information
 en une seule
     • injectée en CSS image-background

     • alourdit potentiellement la maintenance

     • regroupement par unité logique avec en tête
       l’automatisation possible de la génération du sprite

     • http://spriteme.org/ outil utilisable sur n’importe quelle
       page existante

•Toujours apprécier selon le contexte : ici surtout ne pas
 spriter les images des produits qui sont informatives
Cédric Morin / yterium // WebPerf 16 janvier 2012                   14
Chargement asynchrone des morceaux de page

• Objectif
     • Envoyer le HTML le plus vite possible

     • paralléliser la construction de la page (côté client en JS) avec le chargement des
       ressources

     • technique inspirée des BigPipe de Facebook http://www.facebook.com/notes/
       facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/
       389414033919

• En pratique
     • chargement asynchrone par une requête XHR lancée aussitôt que possible, en js
       natif sans jQuery pour ne pas attendre le chargement de ce script

     • HTML injecté dans la page lorsqu’il arrive (HTML ne contient pas de script inline)

     • si IE7 cible a prendre en compte : limiter à 2 blocs parallélisables sur le domaine
       de l’URL principale

Cédric Morin / yterium // WebPerf 16 janvier 2012                                           15
Chargement asynchrone des morceaux de page

• Application
     • sur colonne de droite (avec un fond grisé affiché en attente du chargement)

     • sur pied de page (pas visible au départ)

• Accessibilité
     • hack <noscript><meta http-equiv="refresh"
       content="1;url=index.st.html"></noscript>

     • redirige le visiteur vers une version de la page assemblée côté serveur :
       index.st.html, qui est une version complète même sans javascript

     • En production, on poserait un cookie au visiteur la première fois, et on ne
       lui servirait plus que des pages complètes.

     • robots connus sont repérés côté serveur par leur user-agent et sont
       directement servis par la version complète.

Cédric Morin / yterium // WebPerf 16 janvier 2012                                    16
Lazy-loading

• Principe :
     • ne charger certains éléments de la page que lorsqu’ils deviennent
       visibles par l’internaute

     • Attention aux <img>

          • si attribut src js ne peut pas empêcher le chargement par certains
            navigateurs.

          • Il faut envoyer <img> sans son attribut src

     • repose sur JS, prévoir un repli sans lazyloading si pas de JS

• Ici, alternative sans JS déjà mise en place
     • pas de problème pour reposer sur JS pour la version optimisée

Cédric Morin / yterium // WebPerf 16 janvier 2012                                17
Lazy-loading

•Utilisé sur 3 familles d’éléments :
     •images des produits : attribut original sur les <img>
      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.

     •sur des background-image de décoration

     •sur l’iframe du pied de page



Cédric Morin / yterium // WebPerf 16 janvier 2012                  18
Optimisation des CSS

• Réorganisation
     • feuille unique initiale découpée en unités logiques fonctionnelles

     • une feuille CSS pour chaque unité fonctionnelle

     • une seule feuille CSS dans le document HTML, générée par «Server Side
       Inclusion» qui inclue uniquement les feuilles nécessaires à la page

     • processus réaliste d’un contexte de production

• Minification
     • feuille CSS unique minifiée par CSSTidy https://github.com/Cerdic/
       CSSTidy

     • choisi d’après le comparatif de Stoyan Stefanov http://
       www.phpied.com/css-minifiers-comparison/

Cédric Morin / yterium // WebPerf 16 janvier 2012                           19
Optimisation des CSS

•Non retenu
     •Outils qui permettent de détecter toutes les règles
      inutiles sur une page : pas utilisé car pas réaliste en
      contexte de production

     •séparation des CSS en deux lots

          • core en CSS inline

          • +complements en CSS externe

          • améliorait le start-render mesuré mais pas réel
            => abandonné

Cédric Morin / yterium // WebPerf 16 janvier 2012               20
Optimisation des JS

• Réorganisation
     • Tous les JS inline de la page initiale déportés dans des JS externes (un script
       js par fonctionnalité)

     • Comme pour les CSS, seuls les JS utile à cette page sont retenus

     • jQuery conservé par facilité (on ne s’en passerait pas en production), et
       certaines fonctions ré-écrites pour l’utiliser

     • Concaténation des JS en un seul (Server Side Inclusion) + Minification par le
       Google Closure Compiler http://closure-compiler.appspot.com/home

• Optimisation du chargement
     • en général la règle «appel des JS en pied de page» s’applique

     • Mais ici tout le reste du chargement optimisé, c’est le chargement du script
       JS qui retardait le «onload» de la page

Cédric Morin / yterium // WebPerf 16 janvier 2012                                    21
Optimisation chargement des JS

• Découpage en 2 scripts :
     • un fichier qui contient jQuery et le plugin lazyload

     • et un fichier qui contient l’ensemble des autres scripts

     • chargés en parallèle et asynchrone par un mini-loader jQl développé pour le
       concours https://github.com/Cerdic/jQl

• Optimisation de la place des CSS et JS dans la page
     • tout dans le head pour lancer le chargement «au plus vite»

     • 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


Cédric Morin / yterium // WebPerf 16 janvier 2012                                    22
Factoriser les requêtes JSON

•initialement 16 requêtes JSON
     • pour charger les informations de disponibilité et prix des
       produits.

•Factorisation en 1 seule requête
     • toutes les références des produits de la page en argument

     • réponse sous forme de tableau et dispatching à la reception

     • simulé ici par un fichier statique car le serveur de la Fnac ne
       savait pas servir de cette façon, mais implémentation côté
       serveur très simple en pratique


Cédric Morin / yterium // WebPerf 16 janvier 2012                   23
HTML

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

     •vrai intérêt en production discutable si on Gzip




Cédric Morin / yterium // WebPerf 16 janvier 2012        24
Cookies

• Le marqueur de statistiques posait des cookies sur le domaine .webperf-
  contest.com et contaminait donc tous les sous domaine s1/s2/s3
     • patch du marqueur de statistique pour qu’il pose ses cookies sur entries.webperf-
       contest.com

• Parallélisation et Cookie-free domains
     • sous-domaines s1/s2/s3 utilisés au maximum pour charger les ressources statiques
       (images et CSS).

     • javascripts servis sur le domaine principal entries.webperf-contest.com

          • meilleure parallélisation
            les connexions sur les autres domaines sont toutes chargées a bloc dans IE7

          • chargement async par une requête XHR ne peut provenir se faire que sur le domaine de la page

     • 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.

Cédric Morin / yterium // WebPerf 16 janvier 2012                                                          25
Mise en œuvre et points particulières




Cédric Morin / yterium // WebPerf 16 janvier 2012   26
Rendu

• Remplacer les images par du
  CSS :


     • pour les coins ronds et
       bordures de cadre


     • pour les titre de boite (aplat
       de couleur en CSS au lieu de
       image background)


• Indiquer des attributs width et
  height sur toutes les images




Cédric Morin / yterium // WebPerf 16 janvier 2012   27
Layout

• Supprimer toute la mise en page en
  tableau


• Utiliser LayoutGala


     • http://blog.html.it/layoutgala/


     • Layout Robuste qui permet
       d’avoir toujours le contenu en
       premier dans le HTML




Cédric Morin / yterium // WebPerf 16 janvier 2012   28
Header




•AutoComplétion sur le champ recherche
     • ne charger le script qu’au focus sur le champ

•Menu à onglets
     • seules les images permettaient de garder l’apparence

          • optimisation pour factoriser l’image en mode ON et survol

          • reprise du HTML pour que le menu soit lisible même sans image

Cédric Morin / yterium // WebPerf 16 janvier 2012                       29
• MegaMenu
     • 8ko zippé pour tout le HTML du megamenu

          • evacué du document principal (ce qui permet de remonter le contenu principal dans le document HTML)

          • chargement en fin de hit par une requête AJAX. Injection dans le DOM à la demande (survol d’un onglet)

     • Toutes les images du menu déroulant sont réunies dans un sprite unique, chargé au premier déroulé (le js écrit
       la directive CSS inline car si référencé dans la CSS, l’image est chargée au départ dans certains navigateurs)

     • Sans JS on a accès aux onglets principaux qui emmènent vers les sections du site : pas de perte d’accès aux
       info ni en référencement



Cédric Morin / yterium // WebPerf 16 janvier 2012                                                                    30
Carrousel

• Initialement
     • 3 images (sans alternative) en rotation

     • chargées avec la page

• Optimisation
     • texte plein + image background superposée

     • js qui insère le style background quand besoin de visualiser l’image

     • première image remplacée par une version JPG basse qualité

• => 1 image légère chargée avec la page puis
  rendu&chargement progressif

Cédric Morin / yterium // WebPerf 16 janvier 2012                         31
Les logos



•Redondant avec information texte, deux liens pour
 chaque héro/marque

•Optimisé
     •avec un sprite unique pour les 10 logos (automatisable)

     •logo en background CSS sur un élément <b> inséré
      dans le lien commun avec le texte

     •survol du texte ou logo highlight l’ensemble

Cédric Morin / yterium // WebPerf 16 janvier 2012           32
Image des produits

•Informatives et essentielles

•Mais en général sous le
 fold au chargement de la
 page

•Lazy-loading : ne sont
 chargées que si grande
 fenêtre ou utilisateur
 scrolle



Cédric Morin / yterium // WebPerf 16 janvier 2012   33
Animation

• En colonne de droite un gif animé
     • Poids conséquent 46ko

     • chargé dès le départ, ce qui bloque un slot

     • l’animation ne démarre qu’après une pause sur la première
       image

• Optimisation
     • Remplacé dans le document HTML par un png statique de la
       première frame (13ko)

     • le gif animé est injecté en JS a posteriori, pour faire démarrer
       l’animation

     • 1 hit de plus, mais libère du temps/slot de download au
       chargement initial du document

Cédric Morin / yterium // WebPerf 16 janvier 2012                         34
Univers

•4 blocs avec images décoratives

•Regroupement des 4 images en 1 sprite

•lazyload :
     •insertion en css inline image-background en JS

     •lorsque le premier bloc devient visible par
      scrolling

     •évite le chargement initial du sprite


Cédric Morin / yterium // WebPerf 16 janvier 2012      35
Pied de page&iFrame

• Menu en iframe qu’il était obligatoire de conserver (règlement)

• Chargement async + Lazyload de l’iframe :
     • src vide dans le HTML et injecté par js

     • seulement quand pied de page devient visible




Cédric Morin / yterium // WebPerf 16 janvier 2012                   36
Résultat

http://www.webpagetest.org/result/
101202_3e27be0d330d97f80f92efaf866c6d53/




Cédric Morin / yterium // WebPerf 16 janvier 2012   37
Cédric Morin / yterium // WebPerf 16 janvier 2012   38
Cédric Morin / yterium // WebPerf 16 janvier 2012   39
Cédric Morin / yterium // WebPerf 16 janvier 2012   40
Merci

Présentation téléchargeable sur
http://www.yterium.net/Ma-participation-au-Webperf




Cédric Morin / yterium // WebPerf 16 janvier 2012    41
Références

http://www.yterium.net/Ma-participation-au-Webperf
http://webperf-contest.com/
http://wpo.yterium.net/avant/
http://wpo.yterium.net/contest/
http://www.webpagetest.org/result/101207_6ed820576ae1663a7bf929e648e2dd34/
http://www.webpagetest.org/result/101202_3e27be0d330d97f80f92efaf866c6d53/
https://github.com/Cerdic/webperf-contest-2010

http://imageoptim.pornel.net/
http://spriteme.org/
http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-
for-high-performance/389414033919
http://www.appelsiini.net/projects/lazyload
https://github.com/Cerdic/CSSTidy
http://www.phpied.com/css-minifiers-comparison/
http://closure-compiler.appspot.com/home
https://github.com/Cerdic/jQl
http://blog.html.it/layoutgala/


Cédric Morin / yterium // WebPerf 16 janvier 2012                                  42
Crédits photo

http://www.flickr.com/photos/nojhan/754257252/
http://www.flickr.com/photos/meanestindian/3248185596/
http://www.flickr.com/photos/joshyoung07/3569809500/
http://www.flickr.com/photos/will-wade/6504142953/
http://www.flickr.com/photos/mad_african78/2741067789/
http://www.flickr.com/photos/99655906@N00/489997527/
http://www.flickr.com/photos/alicepopkorn/6042091926/




Cédric Morin / yterium // WebPerf 16 janvier 2012       43

Contenu connexe

Tendances

On test quoi - DCLannion 2017
On test quoi - DCLannion 2017On test quoi - DCLannion 2017
On test quoi - DCLannion 2017Artusamak
 
Cours yeoman backbone box2d
Cours yeoman backbone box2dCours yeoman backbone box2d
Cours yeoman backbone box2dhugomallet
 
WP day Algérie : Concevoir un plugin WordPress
WP day Algérie : Concevoir un plugin WordPressWP day Algérie : Concevoir un plugin WordPress
WP day Algérie : Concevoir un plugin WordPressimath
 
Performances Web Mobile
Performances Web MobilePerformances Web Mobile
Performances Web MobileWilly Leloutre
 
Node, Grunt et leurs copains qui font de l’accessibilité tout seuls !
Node, Grunt et leurs copains qui font de l’accessibilité tout seuls !Node, Grunt et leurs copains qui font de l’accessibilité tout seuls !
Node, Grunt et leurs copains qui font de l’accessibilité tout seuls !vincent aniort
 

Tendances (6)

On test quoi - DCLannion 2017
On test quoi - DCLannion 2017On test quoi - DCLannion 2017
On test quoi - DCLannion 2017
 
Cours yeoman backbone box2d
Cours yeoman backbone box2dCours yeoman backbone box2d
Cours yeoman backbone box2d
 
WP day Algérie : Concevoir un plugin WordPress
WP day Algérie : Concevoir un plugin WordPressWP day Algérie : Concevoir un plugin WordPress
WP day Algérie : Concevoir un plugin WordPress
 
Performances Web Mobile
Performances Web MobilePerformances Web Mobile
Performances Web Mobile
 
Node, Grunt et leurs copains qui font de l’accessibilité tout seuls !
Node, Grunt et leurs copains qui font de l’accessibilité tout seuls !Node, Grunt et leurs copains qui font de l’accessibilité tout seuls !
Node, Grunt et leurs copains qui font de l’accessibilité tout seuls !
 
Optimisation de son site web
Optimisation de son site webOptimisation de son site web
Optimisation de son site web
 

Similaire à Ma participation au WebPerf Contest 2010

jQuery mobile / PhoneGap : contenus dynamiques client-side
jQuery mobile / PhoneGap : contenus dynamiques client-sidejQuery mobile / PhoneGap : contenus dynamiques client-side
jQuery mobile / PhoneGap : contenus dynamiques client-sidemaru.maru
 
Les clés d’un site (beaucoup) plus rapide selon des facteurs qui restent trop...
Les clés d’un site (beaucoup) plus rapide selon des facteurs qui restent trop...Les clés d’un site (beaucoup) plus rapide selon des facteurs qui restent trop...
Les clés d’un site (beaucoup) plus rapide selon des facteurs qui restent trop...SEO CAMP
 
Inclure du Javascript de manière performante
Inclure du Javascript de manière performanteInclure du Javascript de manière performante
Inclure du Javascript de manière performanteJean-Pierre Vincent
 
SEO campus 2019 | Les clés d’un site web (beaucoup) plus rapide selon des fac...
SEO campus 2019 | Les clés d’un site web (beaucoup) plus rapide selon des fac...SEO campus 2019 | Les clés d’un site web (beaucoup) plus rapide selon des fac...
SEO campus 2019 | Les clés d’un site web (beaucoup) plus rapide selon des fac...RESONEO
 
Optimiser réellement le référencement naturel de WordPress
Optimiser réellement le référencement naturel de WordPressOptimiser réellement le référencement naturel de WordPress
Optimiser réellement le référencement naturel de WordPressDaniel Roch - SeoMix
 
SEO & Javascript en 2021 : Challenger les acquis - Alexandre Pinat - SEO CAMP...
SEO & Javascript en 2021 : Challenger les acquis - Alexandre Pinat - SEO CAMP...SEO & Javascript en 2021 : Challenger les acquis - Alexandre Pinat - SEO CAMP...
SEO & Javascript en 2021 : Challenger les acquis - Alexandre Pinat - SEO CAMP...SEO CAMP
 
Le SEO JavaScript démystifié
Le SEO JavaScript démystifiéLe SEO JavaScript démystifié
Le SEO JavaScript démystifiéAdrien Russo
 
Drupagora 2012 Optimisation performances Drupal
Drupagora 2012 Optimisation performances DrupalDrupagora 2012 Optimisation performances Drupal
Drupagora 2012 Optimisation performances DrupalSkilld
 
Supports de cours Fit4Digital future - CMS
Supports de cours Fit4Digital future - CMSSupports de cours Fit4Digital future - CMS
Supports de cours Fit4Digital future - CMSAnnabelle Buffart
 
Améliorer la rapidité de son site web
Améliorer la rapidité de son site webAméliorer la rapidité de son site web
Améliorer la rapidité de son site webEmmanuel Gautier
 
Technical seo tips and tricks actionnables 2018
Technical seo tips and tricks actionnables 2018Technical seo tips and tricks actionnables 2018
Technical seo tips and tricks actionnables 2018Aymen Loukil
 
Un exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHPUn exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHPKristen Le Liboux
 
10 conseils pour booster les performances de votre site sous WordPress
10 conseils pour booster les performances de votre site sous WordPress10 conseils pour booster les performances de votre site sous WordPress
10 conseils pour booster les performances de votre site sous WordPressAurélien Denis
 
Guide d'initialisation d'un projet unity3D
Guide d'initialisation d'un projet unity3DGuide d'initialisation d'un projet unity3D
Guide d'initialisation d'un projet unity3DEsprit Unity
 
Retours sur le concours Webperf 2010
Retours sur le concours Webperf 2010Retours sur le concours Webperf 2010
Retours sur le concours Webperf 2010Jean-Pierre Vincent
 
La vitesse d’un site web : un levier de croissance peu exploité
La vitesse d’un site web : un levier de croissance peu exploitéLa vitesse d’un site web : un levier de croissance peu exploité
La vitesse d’un site web : un levier de croissance peu exploitéFasterize
 

Similaire à Ma participation au WebPerf Contest 2010 (20)

jQuery mobile / PhoneGap : contenus dynamiques client-side
jQuery mobile / PhoneGap : contenus dynamiques client-sidejQuery mobile / PhoneGap : contenus dynamiques client-side
jQuery mobile / PhoneGap : contenus dynamiques client-side
 
Les clés d’un site (beaucoup) plus rapide selon des facteurs qui restent trop...
Les clés d’un site (beaucoup) plus rapide selon des facteurs qui restent trop...Les clés d’un site (beaucoup) plus rapide selon des facteurs qui restent trop...
Les clés d’un site (beaucoup) plus rapide selon des facteurs qui restent trop...
 
Inclure du Javascript de manière performante
Inclure du Javascript de manière performanteInclure du Javascript de manière performante
Inclure du Javascript de manière performante
 
SEO campus 2019 | Les clés d’un site web (beaucoup) plus rapide selon des fac...
SEO campus 2019 | Les clés d’un site web (beaucoup) plus rapide selon des fac...SEO campus 2019 | Les clés d’un site web (beaucoup) plus rapide selon des fac...
SEO campus 2019 | Les clés d’un site web (beaucoup) plus rapide selon des fac...
 
Optimiser réellement le référencement naturel de WordPress
Optimiser réellement le référencement naturel de WordPressOptimiser réellement le référencement naturel de WordPress
Optimiser réellement le référencement naturel de WordPress
 
SEO & Javascript en 2021 : Challenger les acquis - Alexandre Pinat - SEO CAMP...
SEO & Javascript en 2021 : Challenger les acquis - Alexandre Pinat - SEO CAMP...SEO & Javascript en 2021 : Challenger les acquis - Alexandre Pinat - SEO CAMP...
SEO & Javascript en 2021 : Challenger les acquis - Alexandre Pinat - SEO CAMP...
 
Le SEO JavaScript démystifié
Le SEO JavaScript démystifiéLe SEO JavaScript démystifié
Le SEO JavaScript démystifié
 
Drupagora 2012 Optimisation performances Drupal
Drupagora 2012 Optimisation performances DrupalDrupagora 2012 Optimisation performances Drupal
Drupagora 2012 Optimisation performances Drupal
 
Supports de cours Fit4Digital future - CMS
Supports de cours Fit4Digital future - CMSSupports de cours Fit4Digital future - CMS
Supports de cours Fit4Digital future - CMS
 
La performance sur mobile
La performance sur mobileLa performance sur mobile
La performance sur mobile
 
Les performances Web mobile
Les performances Web mobileLes performances Web mobile
Les performances Web mobile
 
Améliorer la rapidité de son site web
Améliorer la rapidité de son site webAméliorer la rapidité de son site web
Améliorer la rapidité de son site web
 
Technical seo tips and tricks actionnables 2018
Technical seo tips and tricks actionnables 2018Technical seo tips and tricks actionnables 2018
Technical seo tips and tricks actionnables 2018
 
Bootstrap
BootstrapBootstrap
Bootstrap
 
Un exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHPUn exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHP
 
10 conseils pour booster les performances de votre site sous WordPress
10 conseils pour booster les performances de votre site sous WordPress10 conseils pour booster les performances de votre site sous WordPress
10 conseils pour booster les performances de votre site sous WordPress
 
Guide d'initialisation d'un projet unity3D
Guide d'initialisation d'un projet unity3DGuide d'initialisation d'un projet unity3D
Guide d'initialisation d'un projet unity3D
 
Développement web mobile avec IONIC 2
Développement web mobile avec IONIC 2Développement web mobile avec IONIC 2
Développement web mobile avec IONIC 2
 
Retours sur le concours Webperf 2010
Retours sur le concours Webperf 2010Retours sur le concours Webperf 2010
Retours sur le concours Webperf 2010
 
La vitesse d’un site web : un levier de croissance peu exploité
La vitesse d’un site web : un levier de croissance peu exploitéLa vitesse d’un site web : un levier de croissance peu exploité
La vitesse d’un site web : un levier de croissance peu exploité
 

Ma participation au WebPerf Contest 2010

  • 1. Ma participation au WebPerf Contest 2010 Cédric Morin / yterium // WebPerf 16 janvier 2012 1
  • 4. Règles • résultat graphique doit être «strictement» identique à l’original • optimisations conservent les fonctionnalités de la page web originale. • Le champs recherche et son autocomplétion • Le défilement doux lorsqu'on clique sur la flèche à droite de "mon panier" • Slider central avec changement automatique et manuel des images • Les menus du haut et sous menus au survol • Les indications "x produits trouvés" qui sont récupérées en ajax • Le système de tracking doit fonctionner (s_code) • Toutes autres fonctionnalités ... Cédric Morin / yterium // WebPerf 16 janvier 2012 4
  • 5. Règles • L'expérience utilisateur doit être préservée (et vous pouvez l'améliorer), par exemple : • Une fois la page chargée, la page doit être aussi fonctionnelle qu'à l'origine • L'accessibilité ne doit pas être sacrifiée (vous pouvez même l'améliorer) • Les optimisations pour référencement doivent être préservées (vous pouvez également les améliorer) • La règle principale est : • agissez comme si c'était votre site ou votre client. Tout sacrifier pour la performance web ne sert à rien. Cédric Morin / yterium // WebPerf 16 janvier 2012 5
  • 6. La page à optimiser • http://www.webpagetest.org/result/ 101207_6ed820576ae1663a7bf929e648e2dd34/ Cédric Morin / yterium // WebPerf 16 janvier 2012 6
  • 7. Cédric Morin / yterium // WebPerf 16 janvier 2012 7
  • 8. Avant • Des indicateurs macroscopiques PageSpeed plutôt corrects • 115 requêtes http pour charger toute la page pour 592ko • 2.44s / 11.03s / 17.2s Cédric Morin / yterium // WebPerf 16 janvier 2012 8
  • 9. Avant •Répartis sur 5 canaux : •2 sur le domaine de la page du concours •1 sur metrics.fnac.com pour le marqueur de stats •2 sur www4.fnac.com, qui concernent des requêtes ajax Cédric Morin / yterium // WebPerf 16 janvier 2012 9
  • 10. Techniques et outils utilisés Cédric Morin / yterium // WebPerf 16 janvier 2012 10
  • 11. Versionner •Tout versionner dès le début •Tout est disponible sous https://github.com/Cerdic/webperf-contest-2010 Cédric Morin / yterium // WebPerf 16 janvier 2012 11
  • 12. 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) pour optimiser les «Repeated view» 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é postérieurement au concours) Cédric Morin / yterium // WebPerf 16 janvier 2012 12
  • 13. Optimisation des images • Optimisation systématique via ImageOptim • interface OSX vers les outils les plus usuels (OptiPNG, PngCrush, JpegOptim) http://imageoptim.pornel.net/ • Pour les images JPG • compromis poids/qualité toujours discutable • mauvaise qualité peut faire perdre des clients, mais poids aussi (par ralentissement des pages) • je me suis fixé le critère d’apparence ‘acceptable en tant que client’, serait sûrement critiqué par un oeil expert (mais non représentatif non plus) • Preloading • en début de <body>, pour démarrer au plus vite le chargement des images et maitriser l’ordre Cédric Morin / yterium // WebPerf 16 janvier 2012 13
  • 14. Sprites •regrouper des images qui ne portent pas d’information en une seule • injectée en CSS image-background • alourdit potentiellement la maintenance • regroupement par unité logique avec en tête l’automatisation possible de la génération du sprite • http://spriteme.org/ outil utilisable sur n’importe quelle page existante •Toujours apprécier selon le contexte : ici surtout ne pas spriter les images des produits qui sont informatives Cédric Morin / yterium // WebPerf 16 janvier 2012 14
  • 15. Chargement asynchrone des morceaux de page • Objectif • Envoyer le HTML le plus vite possible • paralléliser la construction de la page (côté client en JS) avec le chargement des ressources • technique inspirée des BigPipe de Facebook http://www.facebook.com/notes/ facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/ 389414033919 • En pratique • chargement asynchrone par une requête XHR lancée aussitôt que possible, en js natif sans jQuery pour ne pas attendre le chargement de ce script • HTML injecté dans la page lorsqu’il arrive (HTML ne contient pas de script inline) • si IE7 cible a prendre en compte : limiter à 2 blocs parallélisables sur le domaine de l’URL principale Cédric Morin / yterium // WebPerf 16 janvier 2012 15
  • 16. Chargement asynchrone des morceaux de page • Application • sur colonne de droite (avec un fond grisé affiché en attente du chargement) • sur pied de page (pas visible au départ) • Accessibilité • hack <noscript><meta http-equiv="refresh" content="1;url=index.st.html"></noscript> • redirige le visiteur vers une version de la page assemblée côté serveur : index.st.html, qui est une version complète même sans javascript • En production, on poserait un cookie au visiteur la première fois, et on ne lui servirait plus que des pages complètes. • robots connus sont repérés côté serveur par leur user-agent et sont directement servis par la version complète. Cédric Morin / yterium // WebPerf 16 janvier 2012 16
  • 17. Lazy-loading • Principe : • ne charger certains éléments de la page que lorsqu’ils deviennent visibles par l’internaute • Attention aux <img> • si attribut src js ne peut pas empêcher le chargement par certains navigateurs. • Il faut envoyer <img> sans son attribut src • repose sur JS, prévoir un repli sans lazyloading si pas de JS • Ici, alternative sans JS déjà mise en place • pas de problème pour reposer sur JS pour la version optimisée Cédric Morin / yterium // WebPerf 16 janvier 2012 17
  • 18. Lazy-loading •Utilisé sur 3 familles d’éléments : •images des produits : attribut original sur les <img> 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. •sur des background-image de décoration •sur l’iframe du pied de page Cédric Morin / yterium // WebPerf 16 janvier 2012 18
  • 19. Optimisation des CSS • Réorganisation • feuille unique initiale découpée en unités logiques fonctionnelles • une feuille CSS pour chaque unité fonctionnelle • une seule feuille CSS dans le document HTML, générée par «Server Side Inclusion» qui inclue uniquement les feuilles nécessaires à la page • processus réaliste d’un contexte de production • Minification • feuille CSS unique minifiée par CSSTidy https://github.com/Cerdic/ CSSTidy • choisi d’après le comparatif de Stoyan Stefanov http:// www.phpied.com/css-minifiers-comparison/ Cédric Morin / yterium // WebPerf 16 janvier 2012 19
  • 20. Optimisation des CSS •Non retenu •Outils qui permettent de détecter toutes les règles inutiles sur une page : pas utilisé car pas réaliste en contexte de production •séparation des CSS en deux lots • core en CSS inline • +complements en CSS externe • améliorait le start-render mesuré mais pas réel => abandonné Cédric Morin / yterium // WebPerf 16 janvier 2012 20
  • 21. Optimisation des JS • Réorganisation • Tous les JS inline de la page initiale déportés dans des JS externes (un script js par fonctionnalité) • Comme pour les CSS, seuls les JS utile à cette page sont retenus • jQuery conservé par facilité (on ne s’en passerait pas en production), et certaines fonctions ré-écrites pour l’utiliser • Concaténation des JS en un seul (Server Side Inclusion) + Minification par le Google Closure Compiler http://closure-compiler.appspot.com/home • Optimisation du chargement • en général la règle «appel des JS en pied de page» s’applique • Mais ici tout le reste du chargement optimisé, c’est le chargement du script JS qui retardait le «onload» de la page Cédric Morin / yterium // WebPerf 16 janvier 2012 21
  • 22. Optimisation chargement des JS • Découpage en 2 scripts : • un fichier qui contient jQuery et le plugin lazyload • et un fichier qui contient l’ensemble des autres scripts • chargés en parallèle et asynchrone par un mini-loader jQl développé pour le concours https://github.com/Cerdic/jQl • Optimisation de la place des CSS et JS dans la page • tout dans le head pour lancer le chargement «au plus vite» • 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 Cédric Morin / yterium // WebPerf 16 janvier 2012 22
  • 23. Factoriser les requêtes JSON •initialement 16 requêtes JSON • pour charger les informations de disponibilité et prix des produits. •Factorisation en 1 seule requête • toutes les références des produits de la page en argument • réponse sous forme de tableau et dispatching à la reception • simulé ici par un fichier statique car le serveur de la Fnac ne savait pas servir de cette façon, mais implémentation côté serveur très simple en pratique Cédric Morin / yterium // WebPerf 16 janvier 2012 23
  • 24. HTML •Le HTML a été minifié par suppression des espaces redondants et commentaires. J’ai utilisé pour cela de simples expressions régulières •minification beaucoup plus agressive possible •vrai intérêt en production discutable si on Gzip Cédric Morin / yterium // WebPerf 16 janvier 2012 24
  • 25. Cookies • Le marqueur de statistiques posait des cookies sur le domaine .webperf- contest.com et contaminait donc tous les sous domaine s1/s2/s3 • patch du marqueur de statistique pour qu’il pose ses cookies sur entries.webperf- contest.com • Parallélisation et Cookie-free domains • sous-domaines s1/s2/s3 utilisés au maximum pour charger les ressources statiques (images et CSS). • javascripts servis sur le domaine principal entries.webperf-contest.com • meilleure parallélisation les connexions sur les autres domaines sont toutes chargées a bloc dans IE7 • chargement async par une requête XHR ne peut provenir se faire que sur le domaine de la page • 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. Cédric Morin / yterium // WebPerf 16 janvier 2012 25
  • 26. Mise en œuvre et points particulières Cédric Morin / yterium // WebPerf 16 janvier 2012 26
  • 27. Rendu • Remplacer les images par du CSS : • pour les coins ronds et bordures de cadre • pour les titre de boite (aplat de couleur en CSS au lieu de image background) • Indiquer des attributs width et height sur toutes les images Cédric Morin / yterium // WebPerf 16 janvier 2012 27
  • 28. Layout • Supprimer toute la mise en page en tableau • Utiliser LayoutGala • http://blog.html.it/layoutgala/ • Layout Robuste qui permet d’avoir toujours le contenu en premier dans le HTML Cédric Morin / yterium // WebPerf 16 janvier 2012 28
  • 29. Header •AutoComplétion sur le champ recherche • ne charger le script qu’au focus sur le champ •Menu à onglets • seules les images permettaient de garder l’apparence • optimisation pour factoriser l’image en mode ON et survol • reprise du HTML pour que le menu soit lisible même sans image Cédric Morin / yterium // WebPerf 16 janvier 2012 29
  • 30. • MegaMenu • 8ko zippé pour tout le HTML du megamenu • evacué du document principal (ce qui permet de remonter le contenu principal dans le document HTML) • chargement en fin de hit par une requête AJAX. Injection dans le DOM à la demande (survol d’un onglet) • Toutes les images du menu déroulant sont réunies dans un sprite unique, chargé au premier déroulé (le js écrit la directive CSS inline car si référencé dans la CSS, l’image est chargée au départ dans certains navigateurs) • Sans JS on a accès aux onglets principaux qui emmènent vers les sections du site : pas de perte d’accès aux info ni en référencement Cédric Morin / yterium // WebPerf 16 janvier 2012 30
  • 31. Carrousel • Initialement • 3 images (sans alternative) en rotation • chargées avec la page • Optimisation • texte plein + image background superposée • js qui insère le style background quand besoin de visualiser l’image • première image remplacée par une version JPG basse qualité • => 1 image légère chargée avec la page puis rendu&chargement progressif Cédric Morin / yterium // WebPerf 16 janvier 2012 31
  • 32. Les logos •Redondant avec information texte, deux liens pour chaque héro/marque •Optimisé •avec un sprite unique pour les 10 logos (automatisable) •logo en background CSS sur un élément <b> inséré dans le lien commun avec le texte •survol du texte ou logo highlight l’ensemble Cédric Morin / yterium // WebPerf 16 janvier 2012 32
  • 33. Image des produits •Informatives et essentielles •Mais en général sous le fold au chargement de la page •Lazy-loading : ne sont chargées que si grande fenêtre ou utilisateur scrolle Cédric Morin / yterium // WebPerf 16 janvier 2012 33
  • 34. Animation • En colonne de droite un gif animé • Poids conséquent 46ko • chargé dès le départ, ce qui bloque un slot • l’animation ne démarre qu’après une pause sur la première image • Optimisation • Remplacé dans le document HTML par un png statique de la première frame (13ko) • le gif animé est injecté en JS a posteriori, pour faire démarrer l’animation • 1 hit de plus, mais libère du temps/slot de download au chargement initial du document Cédric Morin / yterium // WebPerf 16 janvier 2012 34
  • 35. Univers •4 blocs avec images décoratives •Regroupement des 4 images en 1 sprite •lazyload : •insertion en css inline image-background en JS •lorsque le premier bloc devient visible par scrolling •évite le chargement initial du sprite Cédric Morin / yterium // WebPerf 16 janvier 2012 35
  • 36. Pied de page&iFrame • Menu en iframe qu’il était obligatoire de conserver (règlement) • Chargement async + Lazyload de l’iframe : • src vide dans le HTML et injecté par js • seulement quand pied de page devient visible Cédric Morin / yterium // WebPerf 16 janvier 2012 36
  • 38. Cédric Morin / yterium // WebPerf 16 janvier 2012 38
  • 39. Cédric Morin / yterium // WebPerf 16 janvier 2012 39
  • 40. Cédric Morin / yterium // WebPerf 16 janvier 2012 40
  • 42. Références http://www.yterium.net/Ma-participation-au-Webperf http://webperf-contest.com/ http://wpo.yterium.net/avant/ http://wpo.yterium.net/contest/ http://www.webpagetest.org/result/101207_6ed820576ae1663a7bf929e648e2dd34/ http://www.webpagetest.org/result/101202_3e27be0d330d97f80f92efaf866c6d53/ https://github.com/Cerdic/webperf-contest-2010 http://imageoptim.pornel.net/ http://spriteme.org/ http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages- for-high-performance/389414033919 http://www.appelsiini.net/projects/lazyload https://github.com/Cerdic/CSSTidy http://www.phpied.com/css-minifiers-comparison/ http://closure-compiler.appspot.com/home https://github.com/Cerdic/jQl http://blog.html.it/layoutgala/ Cédric Morin / yterium // WebPerf 16 janvier 2012 42