Dans cet article nous allons voir en détail quelques exemples d'optimisation à effectuer côté serveur web. Je n'ai pas souhaité classer ce post dans la catégorie "Tutoriels" car il s'agit ici plus d'une présentation de certains concepts plutôt que d'une véritable recette à suivre pas à pas. 

Gestion des connexions (TCP) persistantes :

La notion de connexion persistante vise à conserver la connexion TCP entre le client et le serveur pendant un bref instant. Ceci permet d'effectuer plusieurs requêtes HTTP avec une seule connexion. Pour activer les connexions persistantes, il est nécessaire de configurer le serveur de manière à ce qu'il notifie au client qu'il accepte celles-ci. Ceci s'effectue via l'en-tête "Connection" et la valeur "keep-alive" :

keep-alive

Voici un exemple de configuration Apache à placer dans le fichier de configuration (vhost ou htaccess) :

KeepAlive On #active la gestion des connexions persistantes
MaxKeepAliveRequests 100 #nombre de requêtes possibles
KeepAliveTimeout 15 #temps d'inactivité sur une même connexion

Attention, dans le cas où la majorité de vos documents statiques (css, javascripts, images) sont servis par un CDN (Content Network Delivery), il est préférable de ne pas autoriser les connexions persistantes. En effet, on sait dans ce cas que le client ne demandera pas d'autres ressources, il serait donc contre-performant de maintenir les connexions ouvertes.

Optimisation du cache navigateur :

Nous allons voir ici comment manipuler les en-têtes suivantes : expires, cache-control, Etag et Last-modified.

L'en-tête "Expires"

Cet entête définit la date d'expiration d'une ressource au sein du navigateur. Toute ressource arrivant au client avec cette en-tête sera mise en cache et permettra ainsi de délester le serveur Apache. Pour manipuler cette en-tête, il est nécessaire d'activer un module grâce à la commande : "a2enod expires". Vous pouvez ensuite configurer le cache au niveau de votre vhost ou .htaccess :

ExpiresActive On #on active l'expiration 
ExpiresByType image/gif "access plus 1 month" #les gif expirent un mois après leur accèsExpiressByType text/html "modification plus 1 week" #les fichiers HTML sont disponibles une semaine après leur mise à jour.

L'en-tête "Cache-Control"

Cet en-tête permet une plus fine gestion des caches en différenciant les navigateurs et les serveurs proxy. Voici les différentes valeurs possibles :

  • private : mise en cache possible pour les navigateurs mais pas pour les proxy
  • public : mise en cache possible pour les navigateurs et les proxy
  • no-cache : oblige les navigateurs et proxy à revalider systématiquement la ressource à chaque demande auprès du serveur
  • no-store : interdit la mise en cache de la réponse – must-revalidate : la ressource doit être revalidée si elle arrive à expiration (navigateur + proxy)
  • proxy revalidate : la ressource doit être revalidée si elle arrive à expiration (proxy uniquement)
  • max-age=xxx : temps relatif par rapport à la date de la réponse, pendant lequel le contenu est toujours vaide
  • s-maxage=xxx : identique à max-age mais s'applique aux proxy
  • no-transform : empêche les proxy d'encoder ou compresser les ressources

Généralement ces en-tête sont gérés automatiquement au sein des frameworks, applications, CMS etc. il est cependant possible de les configurer via le module "mod_header" d'Apache.

L'en-tête Etag (Entity Tag)

L'Etag correspond à une sorte d'identifiant de ressource. Ainsi, si la ressource est modifiée, l'Etag renvoyé par le serveur dans les en-têtes HTTP changera. L'Etag est structuré de la manière suivante :

  • numéro d'inode de la ressource sur le serveur (INode)
  • taille en octet de la ressource (Size)
  • date et heure de dernière modification (MTime)

La directive Apache "FileEtag" permet de modifier la structure de ce tag.

Compression des documents

Compresser ?

La compression des documents permet d'optimiser le chargement des pages. En effet, les contenus étant de plus en plus riches et variés (images, fichiers audios, fichiers vidéos, SVG, HTML, PDF etc), le poids des pages augmente, la consommation de bande passante est impactée en conséquence. 

Le fonctionnement est le suivant :

  1. Le serveur compresse les données
  2. Les documents compressés sont envoyés par le réseau
  3. Le navigateur décompresse les données avant d'en effectuer le rendu

Avantages / inconvénient ?

Bien que la compression ait un coût en terme de temps processeur, les gains concernant l'utilisation de la bande passante ainsi que le temps de chargement sont conséquents. Alors pourquoi s'en priver ?!

Quels fichiers compresser ? La compression est très efficace sur les données de type HTML, texte, PDF, CSS, Javascript ; en revanche il est quasiement inutile de compresser les fichiers binaires (images, vidéos, flash).

Mise en place sous Apache

  1. Activation du "mod_deflate" grâce à la commande : a2enmod deflate
  2. Configuration du vhost ou .htaccess :
<ifmodule mod_deflate.c>
   AddOutputFilterByType DEFLATE text/plain
   AddOutputFilterByType DEFLATE text/xml
   AddOutputFilterByType DEFLATE text/html
   AddOutputFilterByType DEFLATE text/css
   AddOutputFilterByType DEFLATE application/x-javascript
</ifmodule>
  1. Redémarrer Apache : service Apache2 restart (ou reload)

Conclusion

Cette article vous a présenté différentes oprimisations possibles avec Apache. Pour plus de détails, je vous conseil de lire l'excellent bouquin "Performances PHP – Audit et optimisation LAMP" aux éditions EYROLLES.

Je vous suggère également de consulter ce site http://browserdiet.com/ qui donne de très bon conseils pour améliorer les performances d'un site web. J'ai également rédigé une présentation consacrée aux web performances, ça se passe ici.