Script Tag - async & defer

前端 未结 8 1587
隐瞒了意图╮
隐瞒了意图╮ 2020-11-22 13:52

I have a couple of questions about the attributes async & defer for the

相关标签:
8条回答
  • 2020-11-22 13:59

    HTML5: async, defer

    In HTML5, you can tell browser when to run your JavaScript code. There are 3 possibilities:

    <script       src="myscript.js"></script>
    
    <script async src="myscript.js"></script>
    
    <script defer src="myscript.js"></script>
    
    1. Without async or defer, browser will run your script immediately, before rendering the elements that's below your script tag.

    2. With async (asynchronous), browser will continue to load the HTML page and render it while the browser load and execute the script at the same time.

    3. With defer, browser will run your script when the page finished parsing. (not necessary finishing downloading all image files. This is good.)

    0 讨论(0)
  • 2020-11-22 14:02

    async and defer will download the file during HTML parsing. Both will not interrupt the parser.

    • The script with async attribute will be executed once it is downloaded. While the script with defer attribute will be executed after completing the DOM parsing.

    • The scripts loaded with async does n't guarantee any order. While the scripts loaded with defer attribute maintains the order in which they appear on the DOM.

    Use <script async> when the script does not rely on anything. when the script depends use .

    Best solution would be add the at the bottom of the body.There will be no issue with blocking or rendering.

    0 讨论(0)
  • 2020-11-22 14:04

    This image explains normal script tag, async and defer

    • Async scripts are executed as soon as the script is loaded, so it doesn't guarantee the order of execution (a script you included at the end may execute before the first script file )

    • Defer scripts guarantees the order of execution in which they appear in the page.

    Ref this link : http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html

    0 讨论(0)
  • 2020-11-22 14:11

    I think Jake Archibald presented us some insights back in 2013 that might add even more positiveness to the topic:

    https://www.html5rocks.com/en/tutorials/speed/script-loading/

    The holy grail is having a set of scripts download immediately without blocking rendering and execute as soon as possible in the order they were added. Unfortunately HTML hates you and won’t let you do that.

    (...)

    The answer is actually in the HTML5 spec, although it’s hidden away at the bottom of the script-loading section. "The async IDL attribute controls whether the element will execute asynchronously or not. If the element's "force-async" flag is set, then, on getting, the async IDL attribute must return true, and on setting, the "force-async" flag must first be unset…".

    (...)

    Scripts that are dynamically created and added to the document are async by default, they don’t block rendering and execute as soon as they download, meaning they could come out in the wrong order. However, we can explicitly mark them as not async:

    [
        '//other-domain.com/1.js',
        '2.js'
    ].forEach(function(src) {
        var script = document.createElement('script');
        script.src = src;
        script.async = false;
        document.head.appendChild(script);
    });
    

    This gives our scripts a mix of behaviour that can’t be achieved with plain HTML. By being explicitly not async, scripts are added to an execution queue, the same queue they’re added to in our first plain-HTML example. However, by being dynamically created, they’re executed outside of document parsing, so rendering isn’t blocked while they’re downloaded (don’t confuse not-async script loading with sync XHR, which is never a good thing).

    The script above should be included inline in the head of pages, queueing script downloads as soon as possible without disrupting progressive rendering, and executes as soon as possible in the order you specified. “2.js” is free to download before “1.js”, but it won’t be executed until “1.js” has either successfully downloaded and executed, or fails to do either. Hurrah! async-download but ordered-execution!

    Still, this might not be the fastest way to load scripts:

    (...) With the example above the browser has to parse and execute script to discover which scripts to download. This hides your scripts from preload scanners. Browsers use these scanners to discover resources on pages you’re likely to visit next, or discover page resources while the parser is blocked by another resource.

    We can add discoverability back in by putting this in the head of the document:

    <link rel="subresource" href="//other-domain.com/1.js">
    <link rel="subresource" href="2.js">
    

    This tells the browser the page needs 1.js and 2.js. link[rel=subresource] is similar to link[rel=prefetch], but with different semantics. Unfortunately it’s currently only supported in Chrome, and you have to declare which scripts to load twice, once via link elements, and again in your script.

    Correction: I originally stated these were picked up by the preload scanner, they're not, they're picked up by the regular parser. However, preload scanner could pick these up, it just doesn't yet, whereas scripts included by executable code can never be preloaded. Thanks to Yoav Weiss who corrected me in the comments.

    0 讨论(0)
  • 2020-11-22 14:12

    Keep your scripts right before </body>. Async can be used with scripts located there in a few circumstances (see discussion below). Defer won't make much of a difference for scripts located there because the DOM parsing work has pretty much already been done anyway.

    Here's an article that explains the difference between async and defer: http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/.

    Your HTML will display quicker in older browsers if you keep the scripts at the end of the body right before </body>. So, to preserve the load speed in older browsers, you don't want to put them anywhere else.

    If your second script depends upon the first script (e.g. your second script uses the jQuery loaded in the first script), then you can't make them async without additional code to control execution order, but you can make them defer because defer scripts will still be executed in order, just not until after the document has been parsed. If you have that code and you don't need the scripts to run right away, you can make them async or defer.

    You could put the scripts in the <head> tag and set them to defer and the loading of the scripts will be deferred until the DOM has been parsed and that will get fast page display in new browsers that support defer, but it won't help you at all in older browsers and it isn't really any faster than just putting the scripts right before </body> which works in all browsers. So, you can see why it's just best to put them right before </body>.

    Async is more useful when you really don't care when the script loads and nothing else that is user dependent depends upon that script loading. The most often cited example for using async is an analytics script like Google Analytics that you don't want anything to wait for and it's not urgent to run soon and it stands alone so nothing else depends upon it.

    Usually the jQuery library is not a good candidate for async because other scripts depend upon it and you want to install event handlers so your page can start responding to user events and you may need to run some jQuery-based initialization code to establish the initial state of the page. It can be used async, but other scripts will have to be coded to not execute until jQuery is loaded.

    0 讨论(0)
  • 2020-11-22 14:16

    Both async and defer scripts begin to download immediately without pausing the parser and both support an optional onload handler to address the common need to perform initialization which depends on the script.

    The difference between async and defer centers around when the script is executed. Each async script executes at the first opportunity after it is finished downloading and before the window’s load event. This means it’s possible (and likely) that async scripts are not executed in the order in which they occur in the page. Whereas the defer scripts, on the other hand, are guaranteed to be executed in the order they occur in the page. That execution starts after parsing is completely finished, but before the document’s DOMContentLoaded event.

    Source & further details: here.

    0 讨论(0)
提交回复
热议问题