Performances Web
Guillaume KULAKOWSKI
Expert Technique en Solutions Open
Source @ CGI.
Ambassadeur & Packageur @
FedoraProject.
llaumgui.com
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
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 ?
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 ?
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.
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
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.