Chargement asynchrone : async vs defer et performance
Le chargement asynchrone récupère les ressources sans bloquer la page. Comment fonctionnent async et defer, import() et les images lazy, et les erreurs.
Qu'est-ce que le chargement asynchrone ?
Le chargement asynchrone consiste à récupérer une ressource sans empêcher le navigateur de faire autre chose, comme analyser le HTML ou afficher la page. Sur le web, cela couvre les scripts async et defer, l'import() dynamique, les images à chargement différé et les requêtes fetch. La page reste réactive pendant l'arrivée de la ressource et l'utilise une fois prête.
async vs defer
Un script classique sans l'un ni l'autre attribut est téléchargé et exécuté immédiatement, et le navigateur interrompt l'analyse de la page pendant ce temps. async et defer téléchargent tous deux le script en parallèle de l'analyse. Ils diffèrent par le moment de l'exécution.
- async : s'exécute dès qu'il est téléchargé, ce qui peut interrompre l'analyse, sans garantie d'ordre entre les scripts.
- defer : s'exécute une fois le document analysé, avant
DOMContentLoaded, dans l'ordre d'apparition des scripts dans la page. - type="module" : différé par défaut, donc
defern'a aucun effet.
Ces attributs ne fonctionnent que sur les scripts avec src ; ils ne font rien sur les scripts en ligne. Si les deux sont présents, async l'emporte. Source : MDN, l'élément script.
Exemple
<!-- classic script, blocks parsing -->
<script src="app.js"></script>
<!-- downloads in parallel, runs when ready, any order -->
<script async src="analytics.js"></script>
<!-- downloads in parallel, runs after parsing, in order -->
<script defer src="app.js"></script>
<!-- module scripts are deferred by default -->
<script type="module" src="main.js"></script>Une répartition courante : defer pour le code de votre appli, qui dépend du DOM et d'autres scripts, et async pour les scripts tiers indépendants, comme l'analytique.
Autres formes de chargement asynchrone
- Import dynamique :
import()charge un module ES à la demande et renvoie une promesse. C'est la base du découpage du code, où un morceau n'est chargé qu'au besoin. - Images et iframes différées :
loading="lazy"repousse les ressources hors écran jusqu'à ce que l'utilisateur approche en faisant défiler. Voir le chargement différé (lazy loading). - Requêtes de données : appels
fetchet XHR qui complètent la page après le premier affichage.
Erreurs fréquentes
- async sur des scripts interdépendants. L'ordre n'est pas garanti : un plugin peut s'exécuter avant sa bibliothèque.
- Différer l'image principale. Le plus grand élément visible est en général celui que mesure le Largest Contentful Paint, donc le différer retarde la métrique. Ne différez que ce qui démarre hors écran.
- Scripts bloquants dans le head. Ils retardent le chemin critique de rendu. Différez-les sauf si le premier affichage en a besoin.
- Contenu tardif qui décale la mise en page. Réservez de la place pour le contenu chargé de façon asynchrone.
- Pas de gestion d'erreur. Un
import()oufetchen échec rejette sa promesse ; traitez-le, sinon la fonction n'apparaît jamais, sans bruit.
Chargement asynchrone, tests et supervision
Le chargement asynchrone améliore ce que l'utilisateur voit en premier, mais il déplace le travail au lieu de le supprimer. Les scripts sont toujours téléchargés et exécutés : mesurez donc le résultat dans le navigateur, avec les temps de DOM prêt et les Core Web Vitals, pas seulement les temps de réponse du serveur. Notre guide sur les performances JavaScript montre comment async, defer et le découpage du code influencent le fil principal, et la surveillance de la vitesse des pages suit l'effet de chaque changement régulièrement.
Questions fréquentes sur le chargement asynchrone
Quelle est la différence entre async et defer ?
Les deux téléchargent le script sans bloquer l'analyseur. async l'exécute dès son arrivée, sans ordre garanti. defer l'exécute après l'analyse, avant DOMContentLoaded, dans l'ordre du document.
Lequel utiliser ?
Utilisez defer pour les scripts qui ont besoin du DOM ou dépendent les uns des autres. Utilisez async pour les scripts indépendants, comme l'analytique, qui peuvent s'exécuter dès leur arrivée.
async et defer fonctionnent-ils sur les scripts en ligne ?
Non. Sans attribut src, ils n'ont aucun effet. Les scripts de module sont différés par défaut.
Le chargement asynchrone accélère-t-il une page ?
Il améliore en général la rapidité d'affichage et d'utilisation, car l'analyseur n'est pas retardé. Le travail total reste le même : vérifiez l'effet avec de vraies mesures.
Le lazy loading est-il la même chose que le chargement asynchrone ?
Le lazy loading en est une forme : la ressource n'est récupérée qu'au besoin, par exemple quand une image approche de l'écran. Les scripts async sont récupérés tout de suite, simplement sans bloquer la page.
Termes associés
- Qu'est-ce que Continuous Delivery (CD) ?
- Qu'est-ce que l'edge computing ?
- Qu'est-ce qu'Expo ? Framework React Native, EAS Build et mises à jour
- Hot Module Replacement (HMR) : fonctionnement
- Régénération statique incrémentale (ISR)
- Infrastructure as Code (IaC) : définition, outils, exemples
- Qu'est-ce que le Jamstack ?
- Markdown
Outils LoadFocus connexes
Mettez ce concept en pratique avec LoadFocus, la plateforme même qui propulse tout ce que vous venez de lire.