Performance Web - portail.universita.corsica · Des outils pour automatiser les tâches de...

Post on 24-Jun-2020

3 views 0 download

Transcript of Performance Web - portail.universita.corsica · Des outils pour automatiser les tâches de...

1/58

Performance Web

09/11/2016

www.datasensia.com - www.code4corsica.com @CodeforCorsica

Quand l’optimisation du développeur ne suffit plus

Par

Membre de

2/58

Qui suis-je ?

Damien Grandi

● Formations

– Master S2I en alternance (Corte)

– License SFA Informatique (Corte)

– BTS IRIS (Bastia)

● Parcours professionnel

– Co-Fondateur de DataSensia (Membre de Code4Corsica)

– Concepteur/Développeur chez Urba-Earth

Passioné d’informatique depuis ... longtemps notamment en Web

3/58

Pourquoi optimiser ?

● Penser aux connexion lentes et mobiles

● Améliorer l’expérience utilisateur

– Chargement inférieur à 2 secondes

– Les utilisateurs seront plus enclins à revenir

– En moyenne, 1 utilisateur sur 4 quitte la page web si celle-ci ne se charge pas en moins de 4 secondes

● Influence sur l’indexation de votre site

– Critère de classement par les moteurs de recherche

● Réduction de la charge serveur

● D’autres encore...

4/58

5/58

Après optimisation

Rassurez-vous, vous n’allez pas devoir coder comme cela.

6/58

Sommaire

● Des outils pour automatiser les tâches de déploiement

● Diverses optimisations– Minification / Obfuscation– Images– Gzip– Réduction du nombre de requêtes HTTP

● Cache client– Introduction– Fonctionnement– Assets manager– Observations

● Cache serveur– Introduction– Exemple d’architecture– À quoi ça ressemble avec Nginx– Observation : chargement d’images

7/58

Des outils pour automatiser les tâches de déploiement

8/58

Des outils pour automatiser les tâches de déploiementGulp

● Installer npm (nodejs)● Créer un fichier package.json (optionnel)

● Installer gulp :

● Creer un gulpfile.js● Lancer gulp :

9/58

Des outils pour automatiser les tâches de déploiementgulpfile.js

10/58

Diverses optimisationsMinification / Obfuscation

● Minification :– CSS– HTML

● Obfuscation :– Fichier JS (Javascript)

Impacts :– Réduction du poids– Difficile à lire pour les autres (obfuscation)

11/58

Diverses optimisationsMinification / Obfuscation

Exemple d’obfuscation

12/58

Diverses optimisationsMinification / Obfuscation

● Installer les modules nécessaires :

● Modules utilisés :– gulp-uglify– gulp-clean-css– gulp-htmlmin

13/58

Diverses optimisationsMinification / Obfuscation

gulpfile.js

14/58

Diverses optimisationsImages

● Optimisation des images :– N’utiliser PNG et GIF que si nécessaire– Dimensions correspondant à celles de sortie– N’hésitez pas à utiliser du vectoriel si nécessaire

(SVG)● Dimensions adaptatives● Poids dépendant du niveau de détails● À partir de IE 9

– Compresser en fonction des besoins– Préférer un entrelacement progressif pour les JPEG

(interlaced progressive)

15/58

Diverses optimisationsImages

JPEG Progressif / Non-Progressif

Non Progressif

Progressif

16/58

Diverses optimisationsImages

● Caractéristiques du JPEG Progressif :– Poids plus faible– L’image occupe sa place dans la page bien

avant son chargement complet (~10%)– Supporté par les navigateurs à partir de IE 7

s’affiche à la fin du chargement si non supporté

● Plugins gulp possibles :– gulp-imagemin– gulp-image-optimization

17/58

Diverses optimisationsGZip

● Utiliser la compression GZip :– Généralement une configuration au niveau du

serveur web (Apache, Nginx, etc...)– Peut aussi être spécifié manuellement par page

● Exemple en nodejs (ExpressJS) :

18/58

Diverses optimisationsGZip

● Vérifier avec les devtools du navigateur

Gzip est activé

33ko on été transférés par le réseau au lieu de 94Ko

19/58

Diverses optimisationsRéduction du nombre de requêtes HTTP

● Comprendre les échanges client-serveur– Les en-têtes HTTP ne sont pas compressées

– Plus de fichiers =● Plus de requêtes (limites en requêtes simultanées)● Plus de poids (très légèrement)● Plus de temps de chargement

20/58

Diverses optimisationsRéduction du nombre de requêtes HTTP

● Faisons un test (chaque css fait 960ko)

21/58

Diverses optimisationsRéduction du nombre de requêtes HTTP

● Observations

– Téléchargement bloqué pendant 315 ms

– Temps passé à télécharger : 993 ms

– 9 requêtes effectuées (chaque fichier compressé pèse 3ko)

22/58

Diverses optimisationsRéduction du nombre de requêtes HTTP

● Faisons un nouveau test

– On a fusionné tous les CSS en un seul fichier– Le gros CSS fait 8.5mo

23/58

Diverses optimisationsRéduction du nombre de requêtes HTTP

● Observations

– Téléchargement quasiment pas bloqué

– Temps passé à télécharger : 273 ms

– Une seule requête effectuée (le fichier compressé pèse 25ko)

24/58

Diverses optimisationsRéduction du nombre de requêtes HTTP

● Optimiser grâce à la concaténation– Concaténer les CSS entre eux

– Concaténer les JS entre eux

● Plugin gulp :

– gulp-concat

25/58

Diverses optimisationsRéduction du nombre de requêtes HTTP

Modifications de notre précédent gulpfile.js

26/58

Diverses optimisationsRéduction du nombre de requêtes HTTP

● Aller plus loin– Dans le code source, charger du contenu

dynamiquement avec du javascript :● Lors du scrolling de la page● Lors du click sur une miniature d’image● Cela permet de réduire les données minimales

nécessaires au fonctionnement de la page

– Intégration d’images en data base64● Plugin gulp : gulp-base64

27/58

Diverses optimisationsRéduction du nombre de requêtes HTTP

Intégration d’une image en base64

28/58

Cache client

Questions ?

29/58

Cache clientIntroduction

● Conserve les ressources d’un site web sur l’ordinateur de l’utilisateur

● Permet un gain considérable en performance

– Économise grandement les transferts réseau● Ressources différenciées grâce à leur URI

– Chemin d’accès + Nom du fichier– En clair : nom différent = ressource différente

● Son fonctionnement se base sur la lecture des en-têtes HTTP des fichiers renvoyés par le serveur

30/58

Cache clientFonctionnement

CLIENT WEB

Cache

SERVEUR WEB

HTTP/1.1 200 OK...<html><head><link href=’public/css/style.css’></head>

HTTP/1.1 200 OKExpires: Sat, 08 Oct 2016 13:02:00 GMTLast-Modified: Fri, 07 Oct 2016 11:22:00 GMT...body { background : #000; }

/public/css/style.cssExpires: Sat, 08 Oct 2016 13:02:00 GMTLast-Modified: Fri, 07 Oct 2016 11:22:00 GMT ...body { background : #000; }

GET /

GET /public/css/style.css

1ère visite

1

2

3

La ressource n’existe pas en cache4

31/58

Cache clientFonctionnement

CLIENT WEB

Cache

SERVEUR WEB

/public/css/style.cssExpires: Sat, 08 Oct 2016 13:02:00 GMTLast-Modified: Fri, 07 Oct 2016 11:22:00 GMT ...body { background : #000; }

GET /

2ème visite : ressource non-expirée

La ressource existe en cacheComparaison de l’en-tête « Expires » avec la date actuelle

Ressource non-expirée : Utilisation directe

1

2

GET/public/css/style.css

HTTP/1.1 200 OK...<html><head><link href=’public/css/style.css’></head>

32/58

Cache clientFonctionnement

CLIENT WEB

Cache

SERVEUR WEB

/public/css/style.cssExpires: Sat, 08 Oct 2016 13:02:00 GMTLast-Modified: Fri, 07 Oct 2016 11:22:00 GMT ...body { background : #000; }

GET /

GET/public/css/style.css

3ème visite : ressource expirée

La ressource existe en cacheComparaison de l’en-tête « Expires » avec la date actuelle

Ressource expirée : Interrogation du serveur

Comparaison :

Date de modificationIf-Modified-Since

If-Modified-Since: Fri, 07 Oct 2016 11:22:00 GMT

HTTP/1.1 200 OKExpires: Sat, 15 Oct 2016 15:20:00 GMTLast-Modified: Mon, 10 Oct 2016 15:40:00 GMT...body { background : #FFF; }

En-têtes uniquementHTTP/1.1 304 Not modifiedExpires: Sat, 15 Oct 2016 15:00:00 GMT...

Modifié

Non modifié

1

2

3

4

HTTP/1.1 200 OK...<html><head><link href=’public/css/style.css’></head>

33/58

Cache clientFonctionnement

Quelques notes :

– Il existe plusieurs balises d’en-têtes permettant de comparer des ressources

● Last-Modified avec If-Modified-Since● Etag avec If-None-Match

– Un serveur web n’est pas forcément configuré pour utiliser les valeurs de ces en-têtes par défaut (pour pouvoir renvoyer le statut 304 Not Modified)

● L’implémentation au niveau du code source est possible (exemple : la fonction header en PHP)

– L’explorateur réseau de votre navigateur est votre ami

34/58

Cache clientFonctionnement

Comment exploiter le cache client ?

– En-tête « Expires »● Si la ressource n’expire pas, le client n’interroge pas

le serveur– Énorme réduction du nombre de requêtes HTTP

● Réduction des requêtes simultanées en attente● Réduction du poids transféré par le réseau● Légère réduction de la charge serveur

● Le serveur doit envoyer une valeur correspondant à une date très lointaine

35/58

Cache clientFonctionnement

Problème : si on modifie un fichier

– Comment notifier le client d’une modification d’une ressource si ces ressources n’expirent jamais et que le client n’interroge plus le serveur ?

● Appeler le client et lui dire de vider son cache● Renommons les fichiers modifiés !

– Le cache client différencie deux ressources grâce à leur URI (et donc leur nom)

● Afin de connaitre les nouveaux noms, les fichiers HTML ne doivent pas être conservés en cache, ou conservés mais avec une expiration immédiate (une configuration globale peut être appliquée au niveau du serveur web)

36/58

Cache clientAssets Manager

● Assets Manager : Comment ça marche ?

– Utilise le hash du contenu d’une ressource pour générer un numéro de révision

● Générer un nom de fichier en utilisant le numéro de révision

– Remplace les occurences du chemin d’une ressource dans les fichiers de code source

● Plugins Gulp :

– gulp-rev– gulp-fingerprint

37/58

Cache clientAssets Manager

Exemple avec gulp-rev et gulp-fingerprint

Génération des noms de fichiers et renommage

38/58

Cache clientAssets Manager

Fichier rev-manifest.json

– Association [Nom initial : Nouveau nom]

39/58

Cache clientAssets Manager

Exemple avec gulp-rev et gulp-fingerprint

Remplacement des occurences

40/58

Cache clientAssets Manager

Gulp : Dépendances entre tâches

41/58

Cache clientAssets Manager

Quelques notes :

– D’autres modules gulp existent et peuvent avoir une logique de fonctionnement différente

● gulp-asset ( asset://img/image.png )– Une logique de code exploitant le fichier

rev-manifest.json doit être conçue si nécessité d’obtenir l’URL d’une ressource côté serveur

● Implémenter une fonction (PHP, nodejs...) getAsset(initial_name)

42/58

Cache clientAssets Manager

Exemple en PHP : Sans assets manager

43/58

Cache clientAssets Manager

Exemple en PHP : Avec assets manager

rev-manifest.json

44/58

Cache clientObservations

Observations

Fichier HTML utilisé :

45/58

Cache clientObservations

Aucune ressource en cache

– Toutes les ressources sont intégralement téléchargées

46/58

Cache clientObservations

Ressources en cache : expirées mais inchangées– Le serveur est interrogé– Not Modified : Utilisation des images en cache client

47/58

Cache clientObservations

Ressources en cache : non-expirées– Le serveur n’est pas interrogé– Utilisation directe des images en cache client

48/58

Cache serveur

Questions ?

49/58

Cache serveurIntroduction

● Plusieurs gains

– Réduction de la charge serveur● Évite de recalculer les sorties de pages

dynamiques– Pour tous les clients !

– Réduction du temps de réponse (TTFB)● La ressource est déjà prête

● Mises en place possibles

– Fourni par le logiciel serveur web– Serveur de cache intermédiaire (proxy)

50/58

Cache serveurIntroduction

● Exemple : si on met cette page en cache

– Le HTML généré est conservé en cache serveur● La base de données ne sera requêtée qu’une fois

51/58

Cache serveurExemple d’architecture

CLIENT

SERVEUR

Parefeu

ReverseProxy

Port 80

Cache

Serveur WebPort 5000

52/58

Cache serveurÀ quoi ça ressemble en utilisant Nginx

nginx.conf

53/58

Cache serveurObservation : chargement d’images

● Observation : Premier chargement

– Le cache serveur est vide ● attente de 220ms et TTFB de 125ms

Indisponible dans le cache serveur

54/58

Cache serveurObservation : chargement d’images

Disponible dans le cache serveur

● Observation : Deuxième chargement

– Les images sont dans le cache serveur ● attente de 77ms et TTFB de 49ms

55/58

Conclusion

● Pour mettre en place tout cela

– Choisir une architecture de fichiers adéquate pour les tâches de déploiement

● src => temp1 => temp2 [...] => public– Comprendre la logique client-serveur

● Cache client● Cache serveur

– Définir une limite● On peut toujours optimiser plus mais ça coûte

du temps de le faire

56/58

Merci

damien.grandi@gmail.com

57/58

Sources et Références

– http://sebsauvage.net/rhaa/index.php?2013/07/30/14/35/17-grosses-images-et-petits-debits

– http://www.thibautsoufflet.fr/6-raisons-doptimiser-le-temps-de-chargement-de-votre-site/

– https://www.grafikart.fr/tutoriels/php/etag-last-modified-788

– https://github.com/sindresorhus/gulp-rev

– https://www.npmjs.com/package/gulp-asset

– https://www.npmjs.com/package/gulp-clean-css

– https://www.npmjs.com/package/gulp-concat

– https://www.npmjs.com/package/gulp-fingerprint

– https://www.npmjs.com/package/gulp-uglify

– https://www.npmjs.com/package/gulp-imagemin

– https://www.npmjs.com/package/gulp-htmlmin

– http://gulpjs.com/

– https://nginx.org/en/docs/

58/58

Liens utiles pour tester votre site

– http://www.webpagetest.org/

– http://rigor.com/free

– http://gzipwtf.com/

– https://developers.google.com/speed/pagespeed/insights/

– https://tools.pingdom.com/

– https://asafaweb.com/

– D’autres encore ...