Vous avez un site web, commercial ou pas, et vous le trouvez lent. Il existe plusieurs solutions.
Cet article est pour tous les auditoires: il est simple, mais on entre aussi dans la technique. Mettez vos efforts à réaliser ce que vous comprenez d’abord.
Optimiser ce qui est déjà là
Comment est programmé votre site ? S’il ne s’agit que de pages HTML statiques, vous lisez cet article pour rien car votre site est probablement déjà rapide et le problème se trouve dans la connexion du client (la personne qui accède à votre site) ou dans la connexion du serveur (là où est hébergé votre site).
Si votre script est programmé en PHP ou ASP et qu’il utilise des bases de données, cet article vous concerne.
Ce qui est plus facile, d’abord, c’est de minimiser les opérations en PHP. Il y a toujours plusieurs manières de faire: plus compliqué et plus simple. Assurez-vous d’utiliser toujours la manière simple. Je sais, c’est facile à dire :-).
Mais bon, le site est programmé et vous n’avez pas envie de relire votre code entièrement pour tenter de l’optimiser, et ainsi créer des bugs. Concentrons-nous alors seulement sur les requêtes de bases de données.
Optimiser les requêtes de base de données
D’abord, le B.A.-BA: assurez-vous que votre base de données est sur le même serveur que votre site web, et non sur un serveur situé ailleurs physiquement. Si le serveur n’est pas le même, assurez-vous tout de même que la connexion entre les deux machines est optimale.
Ensuite, assurez-vous d’initier la connexion à votre base de données au début de l’exécution du script et de ne pas l’initier à nouveau dans le script. Si vous n’utilisez pas de Framework ou de MVC qui s’occupe de ça, c’est d’autant plus important de le vérifier. Quand je parle de connexion à la base de données, je parle d’une ligne qui ressemble à ça:
|
$dblink = mysql_connect("somehost", "someuser", "password"); mysql_select_db("BlogPosts",$dblink); |
Le truc, c’est de mettre ceci seulement dans le header.php, si vous en avez un.
Optimiser le nombre de requêtes à la base de données
L’étape suivante est d’observer toutes les requêtes à la base de données que votre script fait. Faites-en l’inventaire (ça vaut la peine) et assurez-vous d’en faire le moins possible à chaque exécution de script.
Par exemple, si vous avez une requête qui va chercher tous les utilisateurs, et une boucle ensuite qui va chercher la liste des numéros de téléphone de chaque utilisateur dans une autre table, peut-être vaudrait-il mieux faire une seule requête avec un JOIN. Pour plus d’informations sur les JOIN, lisez ceci. Cette étape est cruciale car elle peut drastiquement changer le temps d’exécution de votre script.
Ce que vous ne voulez pas, c’est avoir une requête qui se trouve dans une boucle comme:
|
foreach(...){ } for($i=0; $i<...) { } while(...){ } do{ }while(...) |
Optimiser les index de la base de données
Si vous avez des tables dans votre base de données qui ont une taille considérable (plus de 1000 entrées dans la table), il est possible que vous commenciez à voir un ralentissement sur votre site.
Pour contrer cela, les bases de données disposent d’index. C’est comme un dictionnaire: si vous devez parcourir toutes les pages pour chercher un mot en particulier, ce n’est pas optimal. Vaut beaucoup mieux faire une recherche dichotomique (voir la définition de dichotomique). C’est un peu de cette manière que fonctionnent les index.
L’inventaire de vos requêtes de base de données complété, regardez tous les noms de champs que vous avez dans des JOIN ou dans des WHERE. Voici quelques exemples:
|
SELECT * FROM table WHERE champ = 25; SELECT * FROM table1 LEFT JOIN table2 ON table1.champ1 = table2.champ2; |
Vous allez devoir créer des index pour chacun de ces champs. Attention cependant, l’idée n’est pas d’avoir un million d’index par table. Il faut avoir les bons. Si vous vous ramassez avec autant d’index que de champs dans votre table, c’est qu’elle est mal bâtie ou que vos requêtes sont mal bâties.
Avoir trop d’index a l’effet inverse: chaque mise-à-jour de la table ou nouvelle entrée dans la table prend davantage de temps.
Pour plus d’informations sur comment créer des index dans des tables MySQL, cliquez sur ce lien.
Utiliser la cache au maximum et Gzip
Cache, cache, cache, cache. Tout site web d’importance (avec une grande quantité de données ou de pages) a de la cache quelque part.
Qu’est-ce que le cache, exactement ? C’est un stockage temporaire de données pour ne pas avoir à faire trop de requêtes à une base de données ou à autre chose. Il existe donc 2 sortes de cache:
Le cache client
Le client, c’est l’utilisateur qui visite votre site web. S’il recharge à répétition une page, peut-être voudriez-vous dire d’une certaine manière à son navigateur qu’elle n’a pas changé et qu’il est inutile de faire des appels répétés à votre serveur. Il peut aussi être inutile d’avoir à charger à répétition le logo de votre compagnie s’il apparaît de la même manière sur chaque page.
Pour gérer la cache client, il existe plusieurs manières de le faire. Ma préférée est d’utiliser Mod_Expires dans Apache. Voici davantage d’instructions à ce sujet (en anglais).
Le cache serveur
Ce cache est plus important encore que le cache client. Il se décline de plusieurs manières.
D’abord, vous pourriez mettre en cache une forme de compilation de votre code PHP en utilisant APC. Voir plus d’informations concernant la mise en place de APC (en anglais).
Ensuite, vous devriez consulter l’inventaire de vos requêtes à la base de données, et trouver celles qui semblent le plus complexes à réaliser. De là, vous pouvez les mettre en cache dans Memcached (cache dans la mémoire vive) ou en fichier. Cliquez ici pour davantage d’information pour la mise en cache dans Memcached sous PHP.
En passant, il est possible de mettre plusieurs autres choses en cache dans Memcached. Amusez-vous !
Finalement, les pages les plus sollicitées et les plus complexes pourraient être générées en tant que fichier HTML statique. Par exemple, le script vérifie si le fichier HTML de la page d’accueil est généré récemment, et sinon, il l’efface et le regénère. C’est une logique plutôt complexe à mettre en place. Il vous faudra possiblement utiliser la fonction ob_start() en PHP, par exemple.
Tant qu’à parler de cache serveur, je vous recommande d’utiliser un programme qui minimifie (dans le language de développeur !) vos fichiers statiques CSS et Javascript.
En effet, une bonne pratique est d’avoir plusieurs fichiers Javascript afin de bien diviser le code. Je vous recommande ce programme pour le faire « on-the-fly » !
Tant qu’à y être, il pourrait être très intéressant d’utiliser Mod_gzip ou Mod_deflate. Ces deux extensions compressent les données sur votre serveur avant de les envoyer au client qui lui les décompressera à son tour. Le transfert de données est donc minimal, mais le coût en CPU est légèrement augmenté. Pour plus d’informations sur ces deux extensions, cliquez ici.
Optimiser les images
Ensuite, vous voudrez tenter d’avoir des images le moins grosses possible en poids. Si vous utilisez des JPG, c’est facile de les compresser en les créant, mais on perd de la qualité.
Si vous utilisez des PNG (très à la mode par les temps qui courent), il se peut que les dégradés ne soient pas du bon bord.
Passez toutes vos images dans le programme ImageOptim pour économiser de précieux kilo-octets ! Si vous êtes sous Windows, vous pouvez essayer PNGout.
Vérifier vos efforts et trouver d’autres pistes…
À ce points, vous en avez déjà fait beaucoup. Mais réduire la taille de nos pages est une vraie drogue. Je vous recommande d’utiliser l’extension Yslow pour Firefox ou Yslow pour Google Chrome qui vous donnera davantage de conseils et aussi de tester votre site avec l’outil PageSpeed de Google.
Également, j’utilise moi-même très régulièrement l’outil « Inpecter l’élément » de Google Chrome et son onglet « Network ». Pour ce faire, cliquez sur votre page avec le bouton droit de la souris, puis cliquez sur « Procéder à l’inspection de l’élément ». Ensuite, cliquez sur l’onglet « Network ».
Vider la cache de votre navigateur et faites recharger la page. Vous pourrez ainsi voir la taille totale de tous les éléments composant votre page, ainsi que ce qui est chargé et l’ordre dans lequel c’est chargé.
Si vous rechargez la page sans vider votre cache, vous verrez ce qui est servi par la cache client de votre navigateur. Très pratique !
Finalement, je vous laisse sur une note plutôt technique: vous pourriez investiguer l’utilisation de Nginx ou LightHttpd pour votre programme. Il pourrait être intéressant de servir les fichiers statiques au client directement par des processus qui demandent moins de mémoire et laisser les tâches ardues à Apache. Aussi, revoyez votre configuration d’Apache et modifiez-la au besoin. Mais ça, ça sera dans un autre article plus avancé !