Performances Web

Guillaume KULAKOWSKI

Expert Technique en Solutions Open Source @ CGI.
Ambassadeur & Packageur @ FedoraProject.
llaumgui.com

Twitter Google+ LikedIn GitHub

Pourquoi ?

  • Impact direct sur le business.
  • Peut avoir un impact direct sur les coûts
    ex: consommation de services CDN de type Akamai.
  • Impact direct sur le référencement.
  • Nous ne sommes plus patients et n'hésitons pas à aller ailleurs.

Illustrations

  • « Perdre 500ms c’est perdre 20% de trafic pour Google (ou pourquoi il n’y a que dix résultats par page dans les recherches). »
  • « Augmenter la latence de 100ms c’est perdre 1% de ventes pour Amazon. »
  • « Réduire de 25% le poids de la page c’est gagner 25% d’utilisateurs à moyen terme pour Google. »
  • « Perdre 400ms c’est avoir 5 à 9% d’abandons en plus pour Yahoo! sur un site éditorial. »

Guidelines: Yahoo! VS Google ?

Les règles

  • Les 31 règles Google et les 35 règles Yahoo! sont sensiblement les mêmes.
  • Historiquement c'est Yahoo! qui a dégainé ses guidelines le premier.
  • Certaines règles Yahoo! datent (surtout la partie mobile), mais elles sont majoritairement toujours d'actualité.
  • Les règles Google, plus récentes, sont plus hight level.

Nota

  • Cette présentation utilise la classification Yahoo!, AMHA plus claire.
  • Cette présentation se base sur les guidelines de Yahoo! et de Google.
  • Les règles (Yahoo!) jugées obsolètes ont été retirées.

Les catégories Google

Les 31 règles Google sont organisées en 6 catégories :

Les 39 commandements

Les 35 règles Yahoo!: Best Practices for Speeding Up Your Web Site.

Les 31 règles Google: Web Performance Best Practices.

Les 39 commandements

1/7 Content

Moins de requêtes HTTP tu feras

1. Minimize HTTP Requests (Y)

Pourquoi ?

  • Moins de requêtes HTTP = moins de dialogue avec des serveurs = moins de temps.
  • Les navigateurs ont une limite de connexions simultanées par domaine (6 pour Firefox par exemple).

Comment ?

Les requêtes DNS tu reduiras

2. Reduce DNS Lookups (Y) | Minimize DNS lookups (G)

Pourquoi ?

  • Chaque requête DNS a un coût en terme de temps (20 à 120ms).

Comment ?

  • Eviter les appel à 36.000 services ou CDN.
  • Unifier les services & CDN.
  • Si possible, utiliser des chemins à la place de (sous)-domaine.
  • Utiliser des appels asynchrones pour limiter les dégâts.

Les redirections tu utiliseras avec modération

3. Avoid Redirects (Y) | Minimize redirects (G)

Pourquoi ?

  • Le plus court chemin entre A & B est la ligne droite.
  • Les redirections cumulent les temps de chargements.

Comment ?

  • Faire des redirections côté serveur pour limiter l'impact.
  • Faire des redirections côté DNS (CNAME) pour limiter l'impact.

L'AJAX tu mettras en cache

4. Make Ajax Cacheable (Y)

Pourquoi ?

  • Le calcul le plus rapide est celui que l'on ne fait pas.
  • La réponse la plus rapide est celle que l'on n'attend pas (ex: cache navigateur).

Comment ?

  • Traiter les requêtes AJAX comme n'importe quel autre contenu et leur appliquer les bonnes pratiques.
  • Focuser sur les règles suivantes :
    • Gzip Components,
    • Reduce DNS Lookups,
    • Avoid Redirects,
    • Configure ETags.

Les composants non-requis tu chargeras par la suite

5. Post-load Components (Y) | Defer loading of JavaScript (G)

Pourquoi ?

  • Moins d'éléments à charger = moins de temps.
  • Charger toutes les images d'une pages alors qu'on n'affiche que 20% à l'écran est inutile.

Comment ?

Tu anticiperas et preloaderas

6. Preload Components (Y)

Pourquoi ?

  • Peut sembler aller à l'encontre de la précédente: c'est faux.
  • Preloader à un instant "t" = réduire le temps de chargement de l'instant "t+1".
  • Preloader = anticiper.

Comment ?

  • Preload inconditionnel : CSS Sprites.
  • Preload conditionnel : sur des événements qui font engendrer des réponses (ex: commence à remplir un formulaire).
  • Préload anticipé : faire charger des composants avant un lancement pour éviter l'effet "C'était plus rapide avant".

Ton DOM WeightWatchers suivra

7. Reduce the Number of DOM Elements (Y)

Pourquoi ?

  • Plus un DOM est important plus il pèse lourd.
  • Plus le DOM est important plus les manipulation JS du DOM sont coûteuses.

Comment ?

  • Eviter de multiplier les <div> inutiles.

Tes composants tu spliteras

8. Split Components Across Domains (Y) | Parallelize downloads across hostnames (G)

Pourquoi ?

  • Toujours cette limitations de requêtes par domaine.
  • Permettre les téléchargements parallèles.

Comment ?

  • Utiliser plusieurs nom de domaine pour les CDNs (static1, static2, etc...).
  • Attention de ne pas aller à l'encontre de la règles "Reduce DNS Lookups" (2 à 4 maxi).
  • Plus loin: "Maximizing Parallel Downloads in the Carpool Lane" par Tenni Theurer & Patty Chi.

Des iFrame tu n'abuseras point

9. Minimize Number of iframes (Y)

Pourquoi ?

  • Une iFrame permet de charger une page au sein d'une autre page. On multiplie donc les temps de chargement.
  • Les iFrame sont revenues au goût du jour avec le web sociale.

Comment ?

  • Charger "on demand" ou à minima de manière asynchrone pour limiter les effets.

Des erreurs 404 point tu ne feras

10. Avoid 404s (Y) | Avoid bad requests (G)

Pourquoi ?

  • Une 404 n'apporte rien mais coûte.
  • Cercle vicieux car certaines solutions capturent les 404s pour proposer des alternatives. Ça peut donc être très consommateur.

Comment ?

  • Mettre en cache les 404s.
  • Contrôler que les CSS et JS ne génèrent pas de 404s (Firebug).
  • Contrôler les logs serveurs.

Une taille à tes images tu donneras

11. Specify image dimensions (G)

Pourquoi ?

  • Accélère le rendu par le navigateur.

Comment ?

  • Utiliser les propriétés width et height (en plus c'est une bonne pratique d’accessibilité).
  • Attention de ne pas aller à l'encontre de "Do Not Scale Images in HTML".

Les 39 commandements

2/7 Server

Des CDNs tu utiliseras

12. Use a Content Delivery Network (CDN) (Y)

Pourquoi ?

  • Des solutions géographiquement proches de l'utilisateur.
  • Des solutions optimisées pour délivrer des contenus statiques.

Comment ?

Les entête Expires ou Cache-Control tu configureras

13. Add Expires or Cache-Control Header (Y) | Leverage browser caching (G)

Pourquoi ?

  • Permettre de décharger les serveurs et de privilégier le cache navigateur.

Comment ?

ExpiresActive On
AddType image/x-icon .ico
ExpiresByType image/bmp "access plus 30 days"
ExpiresByType image/gif "access plus 30 days"
ExpiresByType image/ico "access plus 30 days"
ExpiresByType image/jpg "access plus 30 days"
ExpiresByType image/jpeg "access plus 30 days"␊
ExpiresByType image/png "access plus 30 days"
ExpiresByType image/x-icon "access plus 30 days"
ExpiresByType text/css "access plus 30 days"
ExpiresByType text/javascript "access plus 30 days"
ExpiresByType application/javascript "access plus 30 days"
ExpiresByType application/x-javascript "access plus 30 days"
ExpiresByType application/x-shockwave-flash "access plus 30 days"

En Gzip tu compresseras

14. Gzip Components (Y) | Enable compression (G)

Pourquoi ?

  • Réduction du poids des éléments.
  • Réduction du temps de transfert.

Comment ?

AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
Header append Vary User-Agent

Les entête ETags tu configureras

15. Configure ETags | Leverage browser caching (G)

Pourquoi ?

  • Les ETags permettent de vérifier que le contenu disponible sur le serveur est bien le même que celui en cache navigateur.

Comment ?

FileETag MTime Size

Ton buffer tu flusheras souvent

16. Flush Buffer Early (Y)

Pourquoi ?

  • Permet de commencer à télécharger du contenu avant la restitution finale de la page par le serveur.

Comment ?

  • Flusher le contenu du <head> de la page par exemple.
  • En PHP, utiliser la methode flush(), par exemple.

Pour l'AJAX, GET tu privilégieras

17. Use GET for Ajax Requests (Y)

Pourquoi ?

  • Une requête POST se fait en 2 temps : émissions des entêtes puis envoi des données.
  • Une requête GET utilise un seul paquet TCP.

Comment ?

  • Utiliser GET lorsque c'est possible.

Des sources vides pour des images point tu ne laisseras passer

18. Avoid Empty Image src (Y)

Pourquoi ?

Comment ?

  • Contrôler votre code source généré.
  • Contrôler vos JS qui peuvent créer des éléments images.

Le charset tu spécifieras

19. Specify a character set (G)

Pourquoi ?

  • Permet au navigateur de commencer à analyser l'HTML et exécuter les scripts immédiatement.

Comment ?

  • Envoyer charset et content type dans les entêtes de la réponse.

Le module PageSpeed

  • Module pour Apache et Nginx.
  • Optimisation automatique des assets.
  • Techniques d'optimisations diverses.
  • Plus de 40 filtres d'optimisations.
  • 1 seul but: accélérer le web !
  • Plus d'info: PageSpeed Module.

Les 39 commandements

3/7 Cookie

Des cookies allégés tu consommeras

20. Reduce Cookie Size (Y)

Pourquoi ?

  • Les cookies sont échangés, ils transitent donc entre le client et le serveur.
  • Diminue le poids des échanges.

Comment ?

  • Supprimer les cookies non nécessaires.
  • Minimiser la taille des cookies le plus possible.
  • Cibler les cookies par sous-domaine et ne pas les échanger avec tous le domaine si ce n'est pas nécessaire.
  • Donner une date d’expiration.
  • Plus loin: "When the Cookie Crumbles" par Tenni Theurer & Patty Chi

Des sous-domaines statiques tu utiliseras

21. Use Cookie-Free Domains for Components (Y) | Serve static content from a cookieless domain (G)

Pourquoi ?

  • Pour les composants (images, CSS, JS) l'échange de cookies n'est pas nécessaire).

Comment ?

  • Utiliser un cache proxy de type Varnish.
  • Utiliser un (sous-)domaine dédié au fichiers statiques.
  • Mieux: utiliser un serveur de type LigHTTPd ou Ngix pour ce (sous-)domaine.

Les 39 commandements

4/7 CSS

Au dessus tes CSS tu placeras

22. Put Stylesheets at Top (Y) | Put CSS in the document head (G)

Pourquoi ?

  • Rend les pages de manière progressive.
  • Lutte contre l'effet de cliping.
  • On a la sensation que la page charge plus rapidement.

Comment ?

  • Mettre le CSS le plus haut possible dans le <head>.

Efficients tes sélecteurs seront

23. Use efficient CSS selectors (Y)

Pourquoi ?

  • Sélecteur non efficient = parcours de DOM importants.
  • Ralenti le temps d'interprétation des pages.

Comment ?

  • Eviter d'utiliser des "*".
  • Préférer les ID et les class au tags.
  • Supprimer les redondances.
  • Utiliser les class plutot que les descendants.
  • Eviter le :hover en dehors des liens.
  • Aller plus loin: "Use efficient CSS selectors"

<link> tu utiliseras

24. Choose <link> Over @import (Y) | Avoid CSS @import (G)

Pourquoi ?

  • Pour certaines versions d'IE @import est mal interprété.
  • Ça revient à mettre un <link> tout en bas de la page.

Comment ?

  • Utiliser:
    <link rel="stylesheet" type="text/css" href="/css/vendor/reset.css" />

Filter point tu n'utiliseras

25. Avoid Filters (Y)

Pourquoi ?

  • IE7 ne supporte pas la transparence des PNG > 8bits.
  • La propriété AlphaImageLoader est une rustine contre performante.

Comment ?

Les expressions tu bannieras

26. Avoid CSS Expressions (Y) (G)

Pourquoi ?

  • Les expression CSS sont puissantes mais dangereuses !
    background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
  • Lancé sous IE5 déprécié en IE8.

Comment ?

  • Si vous ne connaissiez pas les expressions et venez d'en apprendre l’existence, oubliez les !
  • Utiliser Javascript.

Les 39 commandements

5/7 JS

Tout en bas ton JS tu mettras

27. Put Scripts at Bottom (Y)

Pourquoi ?

  • Dans la continuité de "Put Stylesheets at Top".
  • Privilégier le chargement du contenu, puis de l'habillage et en dernier du JS.
  • Toujours cette limite de téléchargements parallèles par domaine.

Comment ?

JS et CSS externes tu utiliseras

28. Make JavaScript and CSS External (Y)

Pourquoi ?

  • JS & CSS externes sont mis en cache (entre autre) par le navigateur.
  • JS & CSS internes alourdissent le poids des pages.

Comment ?

  • Utiliser des fichiers externes.
  • Ne mettez ni CSS ni JS dans le code de vos pages.

JS & CSS tu minifieras

29. Minify JavaScript and CSS (Y) | Combine external JavaScript (G)

Pourquoi ?

  • Commentaires et sauts de ligne ne servent qu'en dev'. Ils alourdissent le poids des fichiers.
  • L'unification en 1 seul fichier contribue à la règle "Minimize HTTP Requests.

Comment ?

Tes scripts une seul fois tu chargeras

30. Remove Duplicate Scripts (Y)

Pourquoi ?

  • 1 seule fois suffit.
  • Nuit à "Minimize HTTP Requests".
  • Augmente le poids des pages.

Comment ?

  • Contrôler le code généré !

Des accès au DOM tu n'abuseras point

31. Minimize DOM Access (Y)

Pourquoi ?

  • Toutes manipulations du DOM en JS a un coût en terme de temps processeur.
  • Ceci peut être amplifié si on ne respecte pas la règle "Reduce the Number of DOM Elements"

Comment ?

  • Mise en cache des références pour accéder plus rapidement aux éléments.
  • Ne pas fixer le layout avec JS.
  • Construire un arbre offline avant de l'ajouter au DOM plutôt que de la construire online de manière séquentielle.

Avec les événements tu y iras molo.

32. Develop Smart Event Handlers (Y)

Pourquoi ?

  • Trop d’événements ralentissent une page.

Comment ?

  • Utiliser les "event delegation" (ex: attacher 1 event au container plutôt qu'1 event sur chaque bouton).
  • Utiliser des DOMReady like plutôt que des onload.

Plus loin encore tu iras

Les 39 commandements

6/7 Images

Tes images tu optimiseras

33. Optimize Images (Y) (G)

Pourquoi ?

  • Réduire le poids au maximum des images.

Comment ?

  • GIF / PNG / JPEG: choisir le bon format.
  • Utiliser des outils de type Pngcrush.

Tes CSS sprites tu optimiseras

34. Optimize CSS Sprites (Y)

Pourquoi ?

  • Réduire le poids au maximum des images.

Comment ?

  • Faire des sprites horizontaux.
  • Combiner des couleur similaires pour pouvoir utiliser du PNG8.
  • Penser mobile et ne pas avoir de sprites trop lourds.

Les images tu ne réduiras pas en HTML

35. Do Not Scale Images in HTML (Y) | Serve scaled images (G)

Pourquoi ?

  • On est en 2013 !
  • Une miniature doit faire dans les 10Ko, pourquoi charger une image de plusieur Mo.

Comment ?

  • Utiliser des vraies miniatures.
  • ImageMagick est ton ami

Ton favicon sera petit et cachable

36. Make favicon.ico Small and Cacheable (Y)

Pourquoi ?

  • Pour avoir un poids de page raisonable.

Comment ?

  • <1k.
  • Configurer les entêtes Expires et/ou Cache-Control Header

Les 39 commandements

7/7 Mobile

Tes composants ne feront pas plus de 25Ko

37. Keep Components Under 25 KB (Y)

Pourquoi ?

  • Historiquement, l'iPhone ne mettait pas en cache les composants de plus de 25K.
  • Bien que plus le cas, ça reste toujours une bonne pratique.
  • Plus d'explications: "iPhone Cacheability – Making it Stick" par Wayne Shea & Tenni Theurer

Comment ?

  • Réduire les poids.
  • Splitter.

Le parsing du JS du défèreras

38. Defer parsing of JavaScript (G)

Pourquoi ?

  • Les navigateurs parsent tout le contenu de <script> afin de servir une page.
  • Diminuer le JavaScript = accélérer le rendu de la page.

Comment ?

  • Voir "Defer loading of JavaScript".
  • Utliser des chargements asynchrones.

Ta page de transition tu cacheras

39. Make landing page redirects cacheable (G)

Pourquoi ?

  • Dans le cas d'une page www.domain.ltd qui redirige vers m.domain.ltd.

Comment ?

  • Redirection 302 avec 1 jour de TTL.
  • Gaffe au autres devices, ne pas oublier le "Vary: User-Agent".

Les outils

Pour Evaluer son site :
Firefox / Firebug avec YSlow

Pour Evaluer son site :
Firefox / Firebug avec Page Speed
ou Chrome avec Page Speed

Questions ?

Crédits & mentions légales

Présentation sous licence Creative Common :

Attribution - Partage dans les Mêmes Conditions 4.0 International
(CC BY-SA 4.0)

Largement inspiré de "Best Practices for Speeding Up Your Web Site" de Yahoo!.

Présentation propulsée par reveal.js.