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

Scripts: async, defer
IT

Vorremo rendere disponibile questo progetto open-source per persone in tutto il mondo.

Aiutaci a tradurre il contenuto di questo tutorial nella tua lingua!

    Cerca in Javascript.info:
    Cerca nel tutorial:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Nei moderni browser gli script sono spesso pi pesanti dell HTML: la loro dimensione di download maggiore e anche i tempi di elaborazione sono pi lunghi.

    Quando il browser carica l HTML e si imbatte in un tag <script>...</script> non pu continuare a costruire il DOM. Deve eseguire lo script al momento. Lo stesso avviene per script esterni <script src="..."></script>: il browser deve aspettare che lo script venga scaricato, eseguito e solo dopo pu processare il resto della pagina.

    Questo conduce a 2 importanti problematiche:

    1. Gli script non possono vedere gli elementi del DOM sotto di essi e quindi non possono aggiungere handler,ecc.
    2. Se c uno script di grandi dimensioni all inizio della pagina esso bloccher la pagina. Gli utente non potranno vedere il contenuto della pagina fino a quando lo script verr scaricato ed eseguito:
    <p>...contenuto prima dello script...</p>
    
    <script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
    
    <!-- Questo non sar visibile finch non sar terminato il caricamento dello script -->
    <p>...contenuto dopo lo script...</p>

    Possiamo per applicare alcuni accorgimenti per ottenere il comportamento desiderato. Per esempio, possiamo mettere lo script in fondo alla pagina. In questo modo vedr gli elementi sopra di esso e non bloccher la visualizzazione della pagina:

    <body>
      ...tutto il contenuto  prima dello script...
    
      <script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
    </body>

    Ma questa soluzione lontana dallessere perfetta. Per esempio, il browser si accorge dello script (e pu iniziarlo a scaricare) solo dopo che stato scaricato tutto il documento HTML. Per pagine HTML molto lunghe ci potrebbe essere un notevole ritardo nel caricamento dello script.

    Queste cose sono invisibili per persone che utilizzano una connessione molto veloce, ma molte persone nel mondo hanno ancora una connessione Internet pi lenta e utilizzano connessioni mobili molto scarse.

    Fortunatamente, ci sono 2 attributi del tag <script> che risolvono il problema per noi: defer e async.

    defer

    Lattributo defer dice al browser che che deve continuare nel caricamento della pagina e caricare lo script in background, per poi eseguire lo script quando caricato.

    Di seguito lo stesso esempio di sopra, ma con defer:

    <p>...contenuto prima dello script...</p>
    
    <script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
    
    <!-- visibile immediatamente -->
    <p>...contenuto dopo lo script...</p>
    • Gli script con defer non bloccano mai la pagina
    • Gli script con defer vengono sempre eseguiti quando il DOM pronto, ma prima dellevento DOMContentLoaded.

    Il seguente esempio lo dimostra:

    <p>...contenuto prima dello script...</p>
    
    <script>
      document.addEventListener('DOMContentLoaded', () => alert("DOM pronto dopo defer!"));
    </script>
    
    <script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
    
    <p>...contenuto dopo lo script...</p>
    1. Il contenuto della pagina viene visualizzato immediatamente.
    2. DOMContentLoaded aspetta il caricamento degli script con lattributo defer. Scatta solo quando lo script (2) scaricato ed eseguito.

    Gli script con defer mantengono il loro ordine, come avviene per i normali script

    Quindi, se abbiamo prima uno script lungo e poi uno pi piccolo, questultimo dovr aspettare.

    <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>
    Lo script piccolo viene scaricato prima, ma eseguito per secondo

    I browser scansionano la pagina per trovare gli script e li scarica in parallelo, per migliorare le performance. Quindi nellesempio sopra entrambi gli script sono scaricati in parallelo. small.js probabilmente verr scaricato prima.

    Ma le specifiche indicano che gli script devono essere eseguito secondo lordine nel document, quindi small.js aspetter long.js per essere eseguito.

    "Lattributo

    Lattributo defer viene ignorato se il tag <script> non ha lattributo src.

    async

    Lattributo async indica che uno script completamente indipendente:

    • La pagina non aspetta gli script con async, il contenuto viene processato e visualizzato
    • DOMContentLoaded and async scripts dont wait each other:
      • DOMContentLoaded pu scattare prima di uno script async (se lo script finisce di caricarsi dopo che il caricamento della pagina terminato)
      • o dopo uno script async (se lo script corto o era in cache)
    • Anche gli altri script non aspettano il caricamento degli script async, e gli script async non aspettano il caricamento degli altri script.

    In altre parole, gli script async vengono caricati in background ed eseguiti quando pronti. Il DOM e gli altri script non restano in attesa che questi vengano caricati. Avremo quindi un script completamente indipendente che verr eseguito al termine del caricamento. Piuttosto semplice, vero?

    Quindi, se abbiamo parecchi script async, potrebbero essere eseguiti in qualunque ordine. Qualunque di essi viene caricato prima viene eseguito prima:

    <p>...contenuto prima degli script...</p>
    
    <script>
      document.addEventListener('DOMContentLoaded', () => alert("DOM pronto!"));
    </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>...contenuto dopo gli script...</p>
    1. Il contenuto della pagina viene mostrato immediatamente: lattributo async non lo blocca.
    2. DOMContentLoaded potrebbe scattare sia prima che dopo gli script async, non c nessuna garanzia in questo caso.
    3. Gli script async non si aspettano a vicenda. Uno script pi piccolo come small.js stato inserito nella pagina per secondo ma probabilmente verr caricato prima di long.js e quindi anche eseguito per primo. Questo viene chiamato un ordine load-first.

    Gli script async sono ottimali quando dobbiamo integrare uno script di terze parti indipendente: contatori, ads, e cos via, visto che essi non dipendono dai nostri script e i nostri script non devono aspettare il loro caricamento:

    <!-- Google Analytics viene aggiunto in questo modo di solito -->
    <script async src="https://google-analytics.com/analytics.js"></script>

    Script dinamici

    Possiamo anche aggiungere uno script dinamicamente usando JavaScript:

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

    Lo script inizia a caricarsi quando allegato al document (*).

    Gli script dinamici si comportano come quelli async di default.

    Cio:

    • Non aspettano nessun altro script e nessuno aspetta loro.
    • Lo script che viene caricato per prima viene anche eseguito per primo (ordine load-first)

    Possiamo cambiare lordine load-first nellordine del document (come i normali script) settando lattributo async a false:

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

    Per esempio, in questo caso abbiamo aggiunto 2 script. Senza script.async=false verrebbero eseguito secondo lordine load-first (small.js probabilmente per primo). Ma con quel flag lordine diventa come nel documento:

    function loadScript(src) {
      let script = document.createElement('script');
      script.src = src;
      script.async = false;
      document.body.append(script);
    }
    
    // long.js viene eseguito per primo grazie a async=false
    loadScript("/article/script-async-defer/long.js");
    loadScript("/article/script-async-defer/small.js");

    Without script.async=false, scripts would execute in default, load-first order (the small.js probably first).

    Again, as with the defer, the order matters if wed like to load a library and then another script that depends on it.

    Riepilogo

    async e defer hanno una cosa in comune: il download di questi script non blocca il rendering della pagina. Quindi lutente pu leggere e comprendere il contenuto della pagina immediatamente.

    Ma ci sono anche differenze essenziali tra loro:

    Order DOMContentLoaded
    async Load-first order. Il loro ordine nel documento non importa dipende da quale script viene caricato prima Irrilevante. Potrebbe essere caricato ed eseguito mentre la pagina non stata ancora stata scaricata. Questo avviene se gli script sono piccoli o in cache, e la pagina abbastanza lunga.
    defer Document order (cio come sono posizionati nella pagina). Vengono eseguiti dopo che il document stato caricato ed elaborato (aspettano se necessario), poco prima dellevento DOMContentLoaded.
    Una pagina senza script dovrebbe essere utilizzabile

    Ricordati che se stai usando defer, allora la pagina visibile prima che lo script sia caricato.

    Quindi lutente potrebbe leggere la pagina ma probabilmente alcuni componenti grafici potrebbero essere non ancora pronti.

    Dovrebbero esserci delle indicazioni di caricamento negli appositi spazi, i bottoni non funzionanti dovrebbero essere disabilitati, per mostrare chiaramente allutente cosa gi pronto o cosa no.

    In pratica, defer utilizzato per script che hanno bisogno di tutto il DOM e/o lordine di esecuzione importante. async utilizzato per script indipendenti, come contatori o ads. E il loro ordine relative di esecuzione non conta.

    Mappa del tutorial

    Commenti

    leggi questo prima di lasciare un commento
    • Per qualsiasi suggerimento - per favore, apri una issue su GitHub o una pull request, piuttosto di lasciare un commento.
    • Se non riesci a comprendere quanto scitto nell'articolo ti preghiamo di fornire una spiegazione chiara.
    • Per inserire delle righe di codice utilizza il tag <code>, per molte righe includile nel tag <pre>, per pi di 10 righe utilizza una sandbox (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page