Optimiser et accélérer les pages web

Apprenez à accélérer vos pages-web !

Pourquoi ?

Si une page met trop longtemps à s'afficher, elle peut vous faire perdre des visiteurs. Suffit de voir : si une page met trois plombes à charger, vous faites quoi, vous ? Vous zapez et passez à autre chose. Vos visiteurs feront pareil.

Vous verrez qu'il ne suffit que de quelques manips pour rendre le chargement de vos pages beaucoup plus rapide.

Sachez que Google et les autres moteurs de recherche favorisent, dans leur résultats, les sites qui s’affichent vite et bien.

Avant de commencer…

Avant toute chose, il faut toujours avoir un code HTML valide. En plus de ne pas faire sérieux, un site plein d’erreur met plus de temps à s’afficher : c’est le navigateur qui doit alors recalculer les corrections.

Pour vous assurez que votre code est valide, faites lui passer le test du validateur HTML & CSS.

Il existe également un tas d’autres petits outils en ligne s'offrent à nous pour aider optimiser un site. Ils analysent vos pages et donnent des solutions.

En voici une sélection :

Produire un code source valide et organisé.

J'ai déjà mentionné qu'il fallait avoir un code source valide W3C. Mais on peut encore faire mieux et avoir un code propre et efficace.

Le code minimal

Certaines balises HTML sont obligatoires. Il faut les mettre.

En particulier, pensez à toujours mettre un encodage de caractère (préférez UTF-8). Sans ça, le navigateur doit deviner lequel est le bon et ça prend du temps.

Un document HTML minimal correspond à ça :

<!DOCTYPE html>
<html lang="fr-fr">
<head>
	<meta charset="UTF-8" />
	<title>Titre de la page web</title>
</head>
<body>
</body>
</html>

Notez la présence de l’attribut lang="fr-fr" sur l’élément <html> : ce dernier n’est pas obligatoire, mais il est bon pour le référencement et pour l’accessibilité.

Dans le <head>, la première chose à mettre est la balise du charset : comme ça, le navigateur sait quel encodage de caractères est utilisé dans tout ce qui suit.

On déclare ensuite le titre du document.

Enfin, on peut refermer l’en-tête et ouvrir le corps du document (body). En pratique, il y a tout un tas d’autre choses à mettre, mais on va voir ça dans ce qui suit.

Sur le HTML

Il s'agit de réduire la quantité de code. Ne pensez pas que ce soit négligeable : on peut facilement gagner 10 % sur la page, et parfois aller jusqu’à 30 %.

Choisir les balises correctement est crucial. L'exemple typique, ce sont les titres. Pour faire un titre, il y'a des balises spéciales qui sont <h1> à >h6> qu'il faut utiliser.
Certains utilisent à la place des <p> améliorés en CSS, ce qu’il ne faut pas faire.
En plus d’ajouter du CSS inutile, ça dénature également le plan du document, qui est implicitement donné par la hiérarchie des titres, entre autres (on parle de la « sémantique »). Ceci est mauvais pour l’accéssibilité, mais aussi pour le référencement…

Le HTML5 comprend énormément de balises : on trouve par exemple une balise pour les abbréviations (<abbr>), une pour le code (<code>), le code affiché (<samp>), les séquences de touches (<kbd>), tout un tas de balises de formulaires…

Apprendre à utiliser ces balises correctement est primordial : il vous évitera des tracas inutiles et vous permettra d’utiliser des fonctions natives des navigateurs, qui sont souvent plus rapides, accessibles, mieux intégrées que tout ce que vous pouvez faire vous-même.
Cela vous facilitera également grandement la vie quand vous voudrez refaire la charte graphique de votre site.

Une liste des éléments HTML est disponible sur le MDN : Référence des éléments HTML | MDN. Je vous recommande d’aller voir ça. Vous y apprendrez très certainement des choses.

Sur le CSS

Les styles sont là pour décorer le HTML, et uniquement décorrer. Bien que ce soit possible, n’utilisez pas le CSS pour modifier la structure du document : pour cela, modifiez votre HTML

Bien qu’il n’existe pas de « CSS obligatoire », je recommande de commencer tous vos fichiers CSS par le code suivant :

@charset "utf-8";

Ceci définit l’encodage de caractères à UTF-8, ce qui est toujours bon.

Ensuite, pour le CSS, apprenez à utiliser les tailles relatives (les em, %, etc.). Si l’utilisateur active le zoom, la page zoomera aussi (contrairement aux pixels, ou au points, par exemple).

Enfin, cela reste du CSS en soi, même si ça ne se voit pas : ajoutez toujours cette balise dans l’en-tête de votre HTML :

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />

Ceci autorise le zoom par l’utilisateur (très important) et rend votre site lisible sur les petits écrans à haute densité de pixels. Ceci vous aidera également pour faire un site compatible mobile et desktop à la fois (mais pour cela, je vous réfère à ce tutoriel).

Le CSS en premier !

Le navigateur charge le CSS en parallèle avec document HTML. Le navigateur attend un bref instant avant de commencer l’affichage de la page : si le CSS est déjà reçu, alors il affichera la page directement comme il faut. Si le CSS était chargé seulement à la fin, le navigateur affichera la page plusieurs fois de suite : sans, puis avec les styles. Ceci coûte cher en performances.

Mettez donc toujours votre CSS dans l’en-tête du document HTML, que ce soit dans une balise style ou dans un fichier externe que vous incluez au moyen d’une balise link.

Attention, ceci est valable pour le CSS, car pour le JavaScript, il est préférable de le placer en bas de la page (voir plus bas).

Séparer le squelette CSS du reste

Aujourd’hui, il est souhaitable de séparrer le CSS en plusieurs fichiers. Google (lien) propose de mettre dans le document HTML le squelette CSS et de mettre le reste dans un fichier séparé. Ceci permet de charger très rapidement les propriétés CSS importantes, et le reste (styles moins importants) un peu plus tard lors du chargement. Le rendu global de la page peut ainsi être amélioré.

Un fichier CSS externe

Si votre site possède plusieurs pages avec le même CSS, il faut faire un fichier CSS externe. Il sera mis >en cache par le navigateur et ainsi ne sera téléchargé qu'une seule fois pour tout le site.

Gardez en tête que dans ce cas le fichier CSS externe ne doit contenir que le CSS commun à toutes les pages (le squelette). Les styles propres à une chaque page doivent être mis dans le <head> de la page concernée.
On évite ainsi que du CSS spécifique à une seule page ne soit téléchargée pour les autres pages inutilement.

Pas de CSS inutile !

Apprenez à optimiser le CSS et regrouper ce qui peut l'être. Par exemple, à l'heure où les CSS3 sont maintenant bien implantés dans tous les navigateurs, le code suivant peut être considéré comme inutile :

border-radius: 10px;
-moz-border-radius: 10px; /* inutile */
-webkit-border-radius: 10px; /* inutile */
-khtml-border-radius: 10px; /* inutile */

À moins que vous ne vouliez vraiment avoir un support pour les navigateurs d’il y a 15 ans, il est préférable de se mettre à jour.

L’exemple avec border-radius est typique, mais il en va en fait de même pour les propriétés box-shadow, transition, animation ou linear-gradient ! Voir mon article Les préfixes CSS obsolètes.

De façon générale, il y a beaucoup trop de CSS dans les pages web et on pourrait se passer d’une très grande partie.

Soyez précis sur les noms des éléments que vous cibler

Quand vous ciblez un élement, il est mieux de spécifier un élement par son ID et sa classe plutôt qu’en remontant tout l’arbre DOM. Le code a.class {…} est donc mieux que html body div div ul li a {…}.

La vitesse vient du fonctionnement interne du navigateur : si vous spécifiez un grand nombre de sélecteurs, il devra tout vérifier, ce qui prend du temps. Alors que si vous spécifiez un ID, ce dernier étant unique, la recherche de l’élément est immédiat.

Plus vous êtes précis, plus le navigateur affichera la page vite.

Il faut rester pragmatique : ne mettez pas non plus des ID partout, mais quand vous savez qu’un élément est et restera unique dans la page (entête, titre général, logo…) alors vous devriez vous en servir : ils sont là pour ça.

Optimisez le rendu CSS des pages

Quand on travaille avec une machine, une chose essentielle est de savoir comment fonctionne la machine « en interne ». Cela permet de faire les bons choix et d’avoir des pratiques compatibles avec la machine.

Faire du HTML, CSS ou JS c’est la même chose : on travaille avec une machine qui est un ordinateur, et plus précisément avec la fonction « navigateur ».

Le fonctionnement d’un navigateur est très complexe, mais si vous savez comment il fonctionne en interne, vous pouvez améliorer le rendu des pages.

Cette vidéo explique comment fonctionne une navigateur. C’est une conférence longue, mais très instructive. Je vous conseille donc de la regarder, justement pour avoir en tête le fonctionnement de la machine qui va interpréter votre code CSS et HTML. Je vous conseille également la lecture de ce blog, écrit par un des auteurs de CSS.

Pour lire une page, il y'a le chargement de la page (du serveur vers le navigateur) et le rendu (du navigateur vers l’écran).

On peut bien avoir une page qui se charge en 0.3s, mais si le navigateur met 2 minutes pour l'afficher, ça ne sert à rien.
N'oublions pas que l'on veut que l'internaute accède rapidement à l'information présente dans vos pages.

Un exemple bien connu est celui des ombres animés sur les blocs dans une page web (article.

Par exemple, j’ai remarqué que l'utilisation abusive des propriétés CSS3 tels que box-shadow et text-shadow faisait laguer la page, et que le rendu était extrêmement lent.

Ces propriétés créent de jolis ombres, mais ces dernières doivent être calculées par le navigateur, et c'est très lourd.
Il y a des tas d’astuces (pour les ombres en particulier) : par exemple, s’il s’agit de mettre une ombre sur un bloc au survol :

.slow-transition {
  box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
  transition: box-shadow 500ms;
}

.slow-transition:hover {
  box-shadow: 0 10px 50px 0 rgba(0, 0, 0, 0.5);
}

Ça semble anodin, mais le navigateur doit recalculler l’ombre et les dégradés à chaque fois qu’on passe la souris sur le bloc.

Il y a une méthode plus rapide :

/* The fast, new way! */
.fast-transition {
  position: relative; /* For positioning the pseudo-element */
  box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
}

.fast-transition::before {
  /* Position the pseudo-element. */
  content: ' ';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;

  /* Create the box shadow at expanded size. */
  box-shadow: 0 10px 50px 0 rgba(0, 0, 0, 0.5);

  /* Hidden by default. */
  opacity: 0;
  transition: opacity 500ms;
}

.fast-transition:hover::before {
  /* Show the pseudo-element on hover. */
  opacity: 1;
}

Ici, on place l’ombre sur un pseudo-élément. Ce pseudo-élément est toujours là, mais c’est son opacité qui change, et c’est son opacité qui est animée au lieu de l’ombre.

Si ceci est plus rapide, c’est parce que le navigateur ne recalcule pas l’ombre à chaque fois. Ici, le navigateur a juste à recalculer l’opacité de l’ombre, ce qui est beaucoup plus rapide (source de l’astuce)

Le rendu de la page est géré par l'ordinateur de l'internaute, et tout le monde n'a pas un PC dernier cri.

Ceci est juste un seul exemple d’astuces qui permet de rendre une page plus fluide, ou de permettre à son rendu d’être plus rapide.

Polices

On peut inclure des polices spéciales dans les pages web, ne les incliant dans le CSS. Ceux-ci devraient être déclarés dès le début du document CSS, au moyen du @font-face.

Concernant le format, woff et woff2 sont spéciales pour le Web. Les formats TTF, SVG, EOT sont possibles aussi, mais sont souvent beaucoup plus lourdes, ce qui rallentit le chargement.

De plus, il faut préciser au navigateur si la police est optionnelle ou importante. En effet, le navigateur va attendre quelques instants d’avoir reçu la police d’criture avant d’afficher le texte. L’affichage peut alors tarder et vos visiteurs vont partir.
Si la police ne sert que pour le corps du texte, il faut dire au navigateur d’afficher le texte avec une police système puis de charger la police à vous. Comme ça vos visiteurs pourront commencer à lire plus vite :

@font-face{
  font-family:'Open Sans';
  font-style:normal;
  font-weight:400;
  font-display: fallback;
  src: local('Open Sans'), url("fonts/open-sans.woff2") format("woff2");
}

Le code important ici est le font-display: fallback. Cela permet d’afficher le texte immédiatement puis d’appliquer la police.

Si vous utilisez une police pour afficher, par exemple, des icônes, et que les polices système risquent d’afficher n’importe quoi, il faut faire l’inverse, avec font-display: block.

Préchargez les polices

Si certains fichiers (polices, mais aussi CSS, par exemple) sont très importants pour l’affichage, il existe la possiblité de les précharger dès que le navigateur charge la page. Comme ça, les polices sont déjà téléchargées lorsque la page vient de finir de l’afficher.
Cela permet aussi de paralléliser le chargement des ressources, ce qui fait gagner du temps pour les ressources peu lourdes (moins de 50 ko environ).

Pour celà, on utiliser un élément <link /> dans l’entête du document, avec le lien vers la ressource et son type de fichier :

<link rel="stylesheet preload" href="style/style.css" as="style" />
<link rel="preload" href="fonts/font.woff2" as="font" type="font/woff2" crossorigin />

Quelques remarques :

Sur le JavaScript (JS)

Les scripts sont des instructions destinées au navigateur. Le JS permet de modifier le code source et de faire d’autres opérations. Il est là pour permettre une interaction entre l’utilisateur et votre page. Normalement, une page web devrait être lisible et utilisateur sans JS.

N’utilisez pas le JS pour styliser une page web.

Les scripts JS sont placés dans un balise script :

<script>
// le code JS ici
</script>

Les anciennes pratiques vous diraient de rajouter un attribut type="text/javascript". Avec le HTML5, une balise script est automatiquement du JS, c’est donc inutile. Même remarque pour les choses comme //<![CDATA[ ... //]]> : ce n’est plus utile.

Les scripts en dernier !

Lors du chargement de la page, l'internaute est intéressé par le texte et les images, pas les instructions destinées au navigateur. En plaçant le JS à la fin du document, ce “superflu” n'est chargé qu'à la fin.

De plus, le navigateur ne peut pas télécharger du JS en parallèle avec le reste du code. Si la page commence avec un pâté de 700Kio de JS, l'internaute devra attendre que le JavaScript ait fini de charger avant de voir apparaître la page elle même.

Pensez à rapatrier les scripts externes (bibliothèques JQuery par exemple) sur votre serveur plutôt que de faire une requête externe sur api.google.com/jquery : ceci est une pratique recommandée contre le pistage, et permet aussi d’être indépendant vis-à-vis du serveur tiers (qui peut tomber en panne ou être arrêté).

C’est un avis personnel, mais à moins d’avoir un site qui fait des millions de vues par jour, je ne recommande pas de « minifier » les scripts (ni le HTML, ni le CSS d’ailleurs). Cela rend le code illisible. De plus, si vous activez la compression GZIP (voir plus loin) des pages web, le gain apporté par la minification est totalement nul.

Les attributs defer et async

Pour le JS, on l’a dit, le téléchargement et l’exécution est bloquant. Si vous avez plusieurs éléments <script>, alors ils ne sont exécutés qu’une fois ils sont tous là, et dans l’ordre où ils apparaissent dans le code source.
Ceci est pratique si les scripts ont besoin les uns des autres dans un ordre précis, mais cela signifie également qu’un seul script très lent peut rallentir toute la page.

Si vous avez un script qui est très gros mais indépendant, il est préférable de le placer tout à la fin. Quand cela n’est pas possible, on peut alors le laisser à sa place et alors lui ajouter un attribut : async. Ceci permet de différer son chargement après le reste de la page. Notez qu’avec cet attribut, non seulement le chargement est différé, mais également son éxécution ! Le JS situé dans un fiché téléchargé de façon asynchrone avec async est éxécuté après l’événement DOMContentLoaded.

Notez que cet attribut peut également fonctionner dans l’autre sens : vu que ce script est indépendant et asynchrone, il sera éxécuté dès qu’il est téléchargé. Il faut donc s’assurer que son code puisse tourner sans les autres scripts de la page, et sans les éléments DOM.

Un autre attribut existe : defer. Celui-ci permet de différer un script tout à la fin du chargement de la page. Un tel script sera alors seulement téléchargé en dernier, mais l’ordre d’éxécution sera inchangé et restera celui de son apparition dans le DOM.

Cet attribut est utile pour forcer le téléchargement d’un script en dernier alors que l’élément <script> lui-même se trouve au début ou au milieu de la page.

Des exemples et un fonctionnement détaillé de ces deux attributs est disponible sur Alsacréations.

Optimiser le code JS

Le JS est exécuté par le navigateur : les scripts plus rapides contribuent donc à un affichage plus rapide des pages.
En règle général, aujourd’hui, toutes les manipulations de code HTML ou CSS au moyen du JavaScript devraient être fait en utilisant les manipulations DOM et les Events.

Un exemple pour montrer que la minipulation DOM est plus rapide : si vous devez vider un élément HTML de ce qu’il contient, il est beaucoup plus rapide d’utiliser de retirer les élément un par un via le DOM que de tout virer d’un coup avec .innerHTML :

var element = document.getElementById('mon_element');
while (element.firstChild) {element.removeChild(element.firstChild);}

Il faut avoir en tête que « moins de code » ne signifie pas forcément « un code plus rapide ». Par exemple :

for (var i=0 ; i<array.length ; i++) {
	...
}

est bien plus lent que ceci :

for (var i=0, len = array.length() ; i<len ; i++) {
	...
}

Dans le premier cas, la longueur du tableau est recalculée à chaque bouclage du for, ce qui prend du temps. Dans le second, le calcul de la longueur du tableau n’est fait qu’une seule fois.

Préférez toujours mettre dans une variable fixe le résultat d’un calcul qui sera emmené à être utilisé plusieurs fois : accéder à une variable est très rapide, mais refaire le calcul à chaque fois peut être extrêmement lent.

Enfin, bien que la praticité de jQuery ou des framework/bibliothèques n’est pas à démontrer pour certaines applications, il sont en général extrêmement lent. Ne l’utilisez donc que pour des applications web complexes qui en ont vraiment besoin, et n’incluez pas une bibliothèque entière si c’est juste pour une petite fonction qu’elle contient.

Pour le JSON

Il peut arriver d’inclure des données JSON dans une page web. Le JSON est du JavaScript : on l’inclut donc dans une balise script. Cependant, le code JSON ne contient que des données et pas d’instructions. On peut pas mal accélérer le chargement de données JSON en lui disant que ce ne sont que des données et pas des instructions : il suffit d’ajouter un attribut type="application/json" :

<script id="jsondata" type="application/json">
// JSON
</script>

Puis, pour récupérer l’objet JSON :

data = JSON.parse(document.getElementById('jsondata').textContent);

Sur de gros ensembles de données, le chargement du JSON peut être jusqu’à 2 fois plus rapide !

Les images

Presque toutes les pages web intègrent des images, pourtant, beaucoup font absolument n’importe quoi.

Apprenez à choisir le bon format de fichier :

En plus de ça, apprenez à optimiser les images. J'ai tout expliqué dans ce tutoriel (car il y a bien trop de choses à dire) ; mais sachez que l'optimisation et le nettoyage des images peut tout changer sur le poids d’une page.

Aussi, quand vous intégrez une image dans une page web, pensez à mettre l’attribut alt="", ainsi que les tailles des images width et height. Le premier est obligatoire, et les deux suivants permettent un rendu beaucoup plus rapide des pages.
Mettez toujours les dimentions des images dans la balise IMG, modifiez-le ensuite (au besoin) en CSS.

Les src-set

Le responsive design permet d’avoir un seul code CSS pour tous les affichages. On peut appliquer ça aux images aussi, en redimentionnant les images. Le problème c’est que si vous avez une image de 2000 px sur un petit écran, il s’affichera, mais la page sera nettement plus lourde que si vous affichez une image plus petite de base.

On peut ainsi spécifier plusieurs images : le navigateur chargera alors seulement l’image adaptée à l’écran sur lequel il s’affiche :

< img src="image.jpg" alt="Une image." srcset="image.jpg 1200w, image-600px.jpg 600w" sizes="50vw" />

Ici, sur un grand écran de 1200 px, l’image image.jpg est chargée. Sur un petit écran de 600 px, l’image image-600px.jpg est chargée, en supposant que la seconde, plus petite, est aussi bien plus légère.

Évidemment, cela vous oblige à avoir deux (ou plus) images sur le serveur, mais généralement cela en vaut clairement la peine.

Le chargement différé (lazyload)

Il existe une pratique qui conciste à ne charger que les images actuelement visibles à l’écran. Ainsi, si certaines images ne sont pas visibles car ils sont tout en bas de la page, ils ne sont chargé que lorsque l’utilisateur scrolle tout en bas. Cela évite de charger des fichiers dans le cas où l’utilise ne scrolle jamais. On appelle ça le « lazy-load ».

Généralement, ceci est opéré en JavaScript, mais il est prévu que le HTML le permette nativement. À ce jour, Chrome et Opera le font déjà.

En pratique, c’est très simple à faire car c’est juste un attribut à ajouter sur vos images :

<!-- image normale -->
<img src="image.png" alt="Une image." />

<!-- image avec lazyload -->
<img src="image.png" alt="Une image." loading="lazy" />

Maintenant, vous pouvez afficher la page et seules les images visibles seront affichées. Les images plus bas dans la page pourront n’être chargées que lorsque vos visiteurs commencent à scroller vers le bas.
Ce n’est vraiment pas grand chose à ajouter mais ça peut peut vous faire gagner beaucoup en terme de performances !

Ceci est particulièrement pertinent pour les images faisant partie du contenu (dans vos articles par exemple). Pour l’image d’en-tête, qui est toujours visible au chargement de la page, cela ne sert à rien.

Base 64

Il y a la possibilité d’inclure les images directement dans le HTML sous forme de texte, grâce au format Base 64. Dans certains cas, ceci peut-être très intéressant question performances.

Les images sont des fichiers externes. Par conséquent, le navigateur envoie une requête au serveur pour la télécharger. On peut optimiser l'image comme on veut, la durée de cette requête n'est pas réductible. Si l’image est minuscule, alors la durée de la requête peut être beaucoup plus longue que la durée de téléchargement. C’est dans ce cas que le Base 64 devient intéressant : il permet de s’affranchir de la requête.

En pratique, c'est très simple à mettre en place. Ici, la seconde ligne utilise l’image en Base64 :

<!-- image normale -->
<img src="/image.png" alt="Une image." />

<!-- image en base64 -->
<img src="data:image/png;base64,f04Hsj7DDfhkj4mFFSfQ...[…]" alt="Une image." />

Où le charabia en rouge après le data:image/png;base64, correspond au codage de l'image en Base 64. La conversion de l'image peut se faire avec des convertisseurs en ligne comme celui ci.

Voici un exemple (si vous voulez voir dans le code source) :

smyle smyle
image normale (338 octets + 1 requête serveur) image affiché par base64 (453 octets + pas de requête serveur)

Le Base 64 produit du code systématiquement 33% plus lourde que l'image dans le fichier. Il faut faire ici un compromis entre la quantité de code en plus et le gain obtenu par la suppression d’une requête HTTP.
En pratique, le Base 64 est utile pour les petits fichiers < 1 ko.

Concernant le fonctionnement de ce système : les images, comme tous les types de fichier, ne sont que du binaire. On peut donc les lire comme des fichiers et comme du texte correspondant au même binaire. Bien-sûr, le texte ne voudra rien dire, mais il conservera l’information contenue dans le fichier image.

L’avantage du texte, c’est qu’on peut le copier-coller directement dans le code source HTML, dans le CSS et même ailleurs. Le navigateur n’a alors pas besoin de faire une requête vers le serveur, et celle-ci est économisée.

Note : le base64 devrait être évité pour le SVG. Le SVG est déjà du code textuel (pas binaire, comme le jpeg par exemple). On peut le placer directement dans le code source d’une page, ou dans le CSS (voir plus bas).

Les SVG

Les SVG sont les images vectorielles.
Ces images sont définies avec des fonctions mathématiques, écrites en XML.

La plupart des logiciels de créations d'images SVG, comme Inkscape incluent des balises inutiles dans les SVG. On peut beaucoup réduire la taille des SVG en supprimant tout ces balises inutiles.

Un outil est celui-ci. Il faut importer l’image, puis jouer sur les paramètres à droite. On voit le taux d’optimisation tout en bas, en vert. Si vous voyez que votre image n’a pas été modifiée mais qu’il y a une amélioration quand-même, gardez le paramètre tel quel et passez au suivant. À la fin, téléchargez votre nouveau SVG.

Inclure directement le SVG dans une page

Le SVG est déjà un langage textuel, et il existe un élément HTML pour le mettre directement dans le code source : <svg></svg>. Ceci économise une requête pour les petits fichiers, à l’instant du base64.

Le SVG étant déjà du texte, utiliser du Base64 pour lui n’est pas utile : ça ne ferait que prendre 33 % de place en plus et de prendre du temps pour le décoder. Si vous mettez par exemple du SVG dans le CSS directement (comme on peut le faire pour de petites icônes individuelles), faites plutôt comme ça :

background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 36 36'><path d='M10.5 15l7.5 7.5 7.5-7.5z' /></svg>");

Sommaire

Apache et le .htaccess

Améliorrer la vitesse de votre site se fait au niveau du code, (voir ci dessus) mais on peut aussi s'aider du serveur, qui possède un tas d’astuces.
Sur un site web, on donner paramètre le serveur au moyen d’un fichier .htaccess (un fichier caché, à la racine de votre site — renseignez-vous auprès de votre hébergeur si besoin).

Le .htaccess est un fichier. Il contient des directives que Apache (le serveur) doit appliquer en fonction des requêtes de l'internaute. (interdire l'accès à tel ou tel fichier, le compresser, le mettre en cache, faire une redirection…).

ATTENTION : Chaque hébergeur n'ayant pas la même configuration d'Apache, il est indispensable de tester le code sur votre espace d'hébergement.

ATTENTION : la syntaxe de ce fichier est extrêmement stricte ! La moindre faute provoquera une erreur 500 du serveur et un site inaccessible.

Enfin, notons que le fichier .htaccess est chargé à chaque requête. Essayez donc de l'adapter pour vos pages. (inutile de mettre 50 directives pour les fichiers *.swf si votre site n'héberge pas de fichiers Flash : ça ne ferait que rallentir votre site).

Ce qui suit sont quelques astuces. Si vous les mettez en place, essayez les un par un, comme ça vous savez tout de suite si quelque chose marche ou ne marche pas. La différence n’est pas forcément visible tout de suite, mais le navigateur, lui le verre.

Essayez aussi avec les outils Google PageSpeed Insight ou GTMetrix : ils vont diront si vos changements sont pris en compte et aussi dans quelle mesure cela constitue une amélioration.

Compresser avec Deflate

Apache est capable de compresser les fichiers avant des les envoyer à l'internaute. C'est ensuite au navigateur de décompresser ce qu'il reçoit. Au final, le temps de chargement diminue et de la bande passante est économisée. Ceci est une astuce très importante.

# compression avec MOD_DEFLATE
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/atom+xml application/rss+xml application/xml application/javascript application/json

# les proxys ne doivent pas décompresser le contenu à la place de l'internaute
Header append Vary User-Agent env=!dont-vary

Le contrôle du cache

Ceci permet de forcer le navigateur à enregistrer les fichiers sur le disque dur. Non seulement les pages s'afficheront bien plus vite dans le futur (le fichiers sont déjà chez l'internaute) mais surtout ça diminue la bande passante consommée.
C'est certainement le moyen le plus efficace pour accélérer le chargement des pages, au moins pour les visiteurs réguliers.

Les navigateurs possèdent une méthode propre à eux pour choisir ce qui est mise en cache, mais ces directives sont prises en compte et elles sont donc utiles.

Ajoutez ceci dans votre fichier .htaccess :

<IfModule mod_headers.c>
  # Prends en compte les polices (formats récents)
  AddType application/x-font-woff .woff
  AddType application/x-font-woff2 .woff2
  # active la mise en cache
  ExpiresActive On
  ExpiresDefault "access plus 1800 seconds"
  # met à 1 an la durée du cache pour les images, le SVG et les polices d’écriture
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType image/x-icon "access plus 1 year"
  ExpiresByType application/javascript "access plus 1 month"
  ExpiresByType application/x-font-woff "access plus 1 year"
  ExpiresByType application/x-font-woff2 "access plus 1 year"
  # met à 1 mois la durée du cache pour les CSS et JS
  ExpiresByType text/css "access plus 1 month"
</IfModule>

Arrangez cela comme vous voulez (types de fichier avec la durée) en fonction de votre site : si vous modifiez le fichier CSS de votre site tout le temps, peut-être est-il bon de lui donner une durée de cache plus courte.

N'oubliez pas non plus d'adapter ce code pour votre site, en fonction des types de fichier que vous êtes emmenés à héberger.

Les ETAG

Les ETAG permettent d'identifier les versions d'un fichier. Si entre deux visites un fichier a été modifié sur votre site, le serveur et le navigateur auront des ETAG différents et le fichier sera renvoyé, sinon il ne renvoie pas.

GTMetrix conseille d'activer les ETAG.
Perso, je serais d'avis de faire comme expliqué ici et les désactiver : à chaque requête, le navigateur et le serveur doivent comparer les ETAG qu'ils ont pour un fichier, ce qui génère du trafic inutilement.

J'ai donc désactivé ça, considérant que la mise en cache suffisait. Pour désactiver :

Header unset ETag
FileETag none

Sommaire

Avec PHP

PHP génère nos pages… Peut-être peut-il nous aider, non ?

La compression GZip

GZip est un moyen de compression utilisé dans divers formats. PHP permet aussi de compresser le contenu (indépendamment de deflate) avant de l'envoyer au navigateur du visiteur.

Il suffit de placer ce code PHP tout en haut de vos pages :

<?php 

function initOutputFilter() {
   ob_start('ob_gzhandler');
   register_shutdown_function('ob_end_flush');
}
initOutputFilter();

?>

À noter : ceci n’est utile en PHP que si votre serveur ne le fait pas déjà lui-même grâce aux directives Apache/NGinx dans le .htaccess.

Mettre les pages en cache de fichiers statiques

Au fur et à mesure que mon site grandissait, avec davantage de pages et d’articles sur le blog, mon site était devenu très lent. J'ai donc mis en place un système de cache de fichiers statiques pour les pages les plus consultées. Le résultat est sans appel :

Avec/sans une mise en cache de pages statiques
Avant/après une mise en place de cette méthode sur ce site (plus la ligne est proche de zéro, mieux c'est)

On voit sur ce graphique que la charge du serveur a très fortement diminuée après la mise en place du cache de fichiers statiques pour les deux principales pages du site. Par ailleurs, le site en est devenu tout de suite très très rapide.

En fait, PHP génère le code HTML d'un page à partir de données brutes, mais une fois que la page est créée et envoyée au visiteur, elle est oubliée. Si un autre visiteur arrive, il doit tout regénérer.
L'idée ici, est de conserver la page au cas où un visiteur demande exactement la même. Ça permet de gagner beaucoup de temps.

Bien sûr, cette méthode n'est à appliquer que sur des pages très demandées et/ou lourdes à générer : sur ce site, c'est le blog et le fichier RSS du blog qui sont de loin les pages les plus demandées. Ce sont les seules pages à bénéficier d'une mise en cache statique.

L'ensemble se fait au moyen de PHP (le code m'a été partagé par Sebsauvage) :

  
$fichierCache = 'cache.dat';
// si la page n'existe pas dans le cache ou si elle a expiré (30 minutes)
// on lance la génération de la page et on la stoke dans un fichier
if (@filemtime($fichierCache)<time()-(1800)) {
    // on démarre la bufferisation : rien n'est envoyé au navigateur
    ob_start();

    // C'est ici qu'il faut placer votre code qui consomme le plus de ressources

    // on recuperre le contenu du buffer
    $contenuCache = ob_get_contents();
    ob_end_flush(); // on termine la bufferisation
    $fd = fopen("$fichierCache", "w"); // on ouvre le fichier cache
    if ($fd) {
        fwrite($fd,$contenuCache); // on écrit le contenu du buffer dans le fichier cache
        fclose($fd);
    }

// sinon le fichier cache existe déjà, on ne génère pas la page
// et on envoie le fichier statique à la place
} else {
    readfile('cache.dat'); // affichage du contenu du fichier
    echo "\n".'<!-- Servi par le cache -->'; // et un petit message
}

Sur mon blog, je suis même allé bien plus loin : j’effectue une cache à deux étages, en tout cas pour la page d’accueil.
La page d’accueil contient toujours les 10 derniers articles contenus dans la base de données. Il n’est donc pas optimal de chercher les 10 derniers articles dans une basse de 1000 articles. À la place, je constitue une mini-base de données contenant juste les dernier articles. Cette mini-base de données est mise à jour quand j’ajoute un nouvel article seulement.

En plus de ça, j’utilise la méthode ci-dessus, avec le fichier statique, sauf que quand le fichier statique est expiré, je ne fais plus une requête sur la base de données, mais sur la mini-base de données, pour encore plus de rapidité.

Astuces pour le code PHP

Ce que suit sur le PHP sont des astuces toutes simples mais qui font gagner énormément de temps et diminuent aussi un peu la charge du serveur.

La taille des tableaux dans les boucles

Comme pour le JS un peu plus haut, quand vous faites une boucle sur un tableau, pensez à mettre la taille du tableau dans une variable :

<?php 
// soit un tableau $tableau[]
   for ($i=0, $longueur = sizeof($tableau); $i < $longueur; $++) {
      echo $tableau[$i];
   }
?>

La durée de chargement de la page est divisé par 500 ici.

(source : http://www.phpbench.com/)

Des fonctions plus gourmandes en ressources que d'autres

Certains tests comme celui ci montrent qu'il y'a clairement des différences entres deux fonctions équivalentes.

Je ne vais pas recopier tout le test, vous lirez si vous voulez, mais l’idée générale est que chaque fonction a ses spécificités (require() et require_once() ont des buts précis, par exemple et il faut les utiliser au bon moment).

Des fonctions consommatrices de ressources

Les fonctions comme la création et les redimensionnement d'images (imageresize()) sont très gourmandes en ressources. D'ailleurs, il n'est pas rare que les hébergeurs désactivent cette fonction.

Si vous devez inclure une image faite en PHP dans une page, il faut mieux la créer une seule fois, la stocker dans un dossier puis l'importer normalement. On va pas demander à PHP de refaire l'image à chaque fois, hein ?

Sommaire

Sommaire

Page crée en juin 2010 - Dernière mise à jour le samedi 8 décembre 2019
Adresse de la page : https://lehollandaisvolant.net/tuto/pagespd