[ Web Proxy ]
URL:
Viewing: https://fr.javascript.info/script-async-defer [Back]  [Original]

Les scripts: async, defer
FR

Nous souhaitons rendre ce projet open source disponible pour les gens du monde entier.

Aidez-nous traduire le contenu de ce tutoriel dans votre langue!

    Rechercher sur Javascript.info:
    Rechercher dans le tutoriel:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Dans les sites Web modernes, les scripts sont souvent plus lourds que le HTML: leur taille de tlchargement est plus grande et le temps de traitement est galement plus long.

    Lorsque le navigateur charge le HTML et rencontre une balise <script>...</script>, il ne peut pas continuer construire le DOM. Il doit excuter le script de suite. Il en va de mme pour les scripts externes <script src ="..."></script>: le navigateur doit attendre le tlchargement du script, lexcuter, puis traiter le reste de la page.

    Cela conduit deux problmes importants:

    1. Les scripts ne peuvent pas voir les lments DOM en dessous deux, ils ne peuvent donc pas ajouter de gestionnaires, etc.
    2. Sil y a un script volumineux en haut de la page, il bloque la page. Les utilisateurs ne peuvent pas voir le contenu de la page tant quil nest pas tlcharg et excut:
    <p>...content before script...</p>
    
    <script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
    
    <!-- Ceci n'est pas visible tant que le script n'est pas charg -->
    <p>...content after script...</p>

    Il existe quelques solutions pour contourner cela. Par exemple, nous pouvons mettre un script en bas de page. Comme a, il peut voir les lments au-dessus, et cela ne bloque pas laffichage du contenu de la page:

    <body>
      ...all content is above the script...
    
      <script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
    </body>

    Mais cette solution est loin dtre parfaite. Par exemple, le navigateur remarque le script (et peut commencer le tlcharger) uniquement aprs avoir tlcharg le document HTML complet. Pour les longs documents HTML, cela peut tre un retard notable.

    De telles choses sont invisibles pour les personnes utilisant des connexions trs rapides, mais de nombreuses personnes dans le monde ont encore des vitesses Internet lentes et utilisent une connexion Internet mobile loin dtre parfaite.

    Heureusement, il y a deux attributs de <script> qui rsolvent le problme pour nous: defer et async.

    defer

    Lattribut defer indique au navigateur de ne pas attendre le script. Au lieu de cela, le navigateur continuera traiter le HTML, construire le DOM. Le script se charge en arrire-plan, puis sexcute lorsque le DOM est entirement construit.

    Voici le mme exemple que ci-dessus, mais avec defer :

    <p>...content before script...</p>
    
    <script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
    
    <!-- visible immdiatement -->
    <p>...content after script...</p>
    • Les scripts avec defer ne bloquent jamais la page.
    • Les scripts avec defer sexcutent toujours lorsque le DOM est prt, mais avant lvnement DOMContentLoaded.

    Lexemple suivant montre que:

    <p>...content before scripts...</p>
    
    <script>
      document.addEventListener('DOMContentLoaded', () => alert("DOM ready after defer!")); // (2)
    </script>
    
    <script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
    
    <p>...content after scripts...</p>
    1. Le contenu de la page saffiche immdiatement.
    2. DOMContentLoaded attend le script diffr. Il ne se dclenche que lorsque le script (2) est tlcharg et excut.

    Les scripts diffrs conservent leur ordre relatif, tout comme les scripts classiques.

    Donc, si nous avons dabord un long script, puis un plus petit, alors ce dernier attend.

    <script defer src="https://javascript.info/article/script-async-defer/long.js"></script>
    <script defer src="https://javascript.info/article/script-async-defer/small.js"></script>

    Les navigateurs analysent la page la recherche de scripts et les tlchargent en parallle pour amliorer les performances. Ainsi, dans lexemple ci-dessus, les deux scripts se tlchargent en parallle. Le small.js se termine probablement en premier.

    Mais lattribut defer, en plus de dire au navigateur de ne pas bloquer, garantit que lordre relatif est conserv. Ainsi, mme si small.js se charge en premier, il attend et sexcute toujours aprs lexcution de long.js. Mais la spcification exige que les scripts sexcutent dans lordre des documents, donc elle attend que long.js sexcute.

    ```smart header="L'attribut `defer` est uniquement pour les scripts externes"
    L'attribut `defer` est ignor si la balise `<script>` n'a pas de `src`.

    async

    • Le navigateur ne bloque pas les scripts async (comme defer).
    • Dautres scripts nattendent pas les scripts async, et les scripts async ne les attendent pas.
    • DOMContentLoaded et les scripts asynchrones ne sattendent pas :
      • DOMContentLoaded peut se produire la fois avant un script asynchrone (si un script async termine le chargement une fois la page termine)
      • ou aprs un script async (si un script async est court ou tait dans le cache HTTP)

    En dautres termes, les scripts async se chargent en arrire-plan et sexcutent lorsquils sont prts. Le DOM et les autres scripts ne les attendent pas, et ils nattendent rien. Un script entirement indpendant qui sexcute lorsquil est charg. Aussi simple que cela puisse tre, non ?

    Donc, si nous avons plusieurs scripts async, ils peuvent sexcuter dans nimporte quel ordre. Premier charg premier excut:

    <p>...content before scripts...</p>
    
    <script>
      document.addEventListener('DOMContentLoaded', () => alert("DOM ready!"));
    </script>
    
    <script async src="https://javascript.info/article/script-async-defer/long.js"></script>
    <script async src="https://javascript.info/article/script-async-defer/small.js"></script>
    
    <p>...content after scripts...</p>
    • Le contenu de la page apparat immdiatement: async ne la bloque pas.
    • DOMContentLoaded peut arriver soit avant ou aprs async, aucune garantie ici.
    • Les scripts asynchrones nattendent pas les uns les autres. Un script plus petit small.js passe en second, mais se charge probablement avant long.js, donc sexcute en premier. Cest ce quon appelle une commande load-first.

    Les scripts asynchrones sont parfaits lorsque nous intgrons un script tiers indpendant dans la page: compteurs, publicits, etc., car ils ne dpendent pas de nos scripts et nos scripts ne doivent pas les attendre:

    <!-- Google Analytics est gnralement ajout comme ceci -->
    <script async src="https://google-analytics.com/analytics.js"></script>
    Lattribut async est uniquement pour les scripts externes

    Tout comme defer, lattribut async est ignor si la balise <script> na pas de src.

    Les scripts dynamiques

    Il existe un autre moyen important dajouter un script la page.

    Nous pouvons galement ajouter un script dynamiquement en utilisant JavaScript:

    let script = document.createElement('script');
    script.src = "/article/script-async-defer/long.js";
    document.body.append(script); // (*)

    Le script commence se charger ds quil est ajout au document (*).

    Les scripts dynamiques se comportent comme asynchrones par dfaut.

    Cest--dire :

    • Ils nattendent rien, rien ne les attend.
    • Le script qui se charge en premier sexcute en premier (load-first).
    let script = document.createElement('script');
    script.src = "/article/script-async-defer/long.js";
    
    script.async = false;
    
    document.body.append(script);

    Par exemple, nous ajoutons ici deux scripts. Sans script.async=false, ils sexcuteraient dans lordre de chargement (le small.js probablement en premier). Mais avec, lordre est comme dans le document:

    function loadScript(src) {
      let script = document.createElement('script');
      script.src = src;
      script.async = false;
      document.body.append(script);
    }
    
    // long.js s'excute en premier  cause de async=false
    loadScript("/article/script-async-defer/long.js");
    loadScript("/article/script-async-defer/small.js");

    Rsum

    Async et defer ont un point commun: le tlchargement de tels scripts ne bloque pas le rendu des pages. Ainsi, lutilisateur peut lire le contenu de la page et se familiariser immdiatement avec la page.

    Mais il existe galement des diffrences essentielles entre eux:

    Lordre DOMContentLoaded
    async Load-first. Leur ordre dans le document na pas dimportance premier charg, premier excut Sans importance. Peut se charger et sexcuter alors que le document na pas encore t entirement tlcharg. Cela se produit si les scripts sont petits ou mis en cache et que le document est suffisamment long.
    defer Ordre de document (tel quil apparat dans le document). Excute aprs le chargement et lanalyse du document (ils attendent si ncessaire), juste avant DOMContentLoaded.

    En pratique, defer est utilis pour les scripts qui ont besoin de tout le DOM et/ou leur ordre dexcution relatif est important.

    Et async est utilis pour des scripts indpendants, comme des compteurs ou des publicits. Et leur ordre dexcution relatif na pas dimportance.

    La page sans scripts devrait tre utilisable

    Veuillez noter que si vous utilisez defer ou async, lutilisateur verra alors la page avant le chargement du script.

    Lutilisateur peut donc lire la page, mais certains composants graphiques ne sont probablement pas encore prts.

    Il devrait y avoir des indications de chargement aux bons endroits et les boutons dsactivs devraient safficher comme tels, afin que lutilisateur puisse voir clairement ce qui est prt et ce qui ne lest pas.

    Carte du tutoriel

    Commentaires

    lire ceci avant de commenter
    • Si vous avez des amliorations suggrer, merci de soumettre une issue GitHub ou une pull request au lieu de commenter.
    • Si vous ne comprenez pas quelque chose dans l'article, merci de prciser.
    • Pour insrer quelques bouts de code, utilisez la balise <code>, pour plusieurs lignes enveloppez-les avec la balise <pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page