If we assume all web browsers understand the – CertainPerformance Dec 13 '19 at 05:03

  • So your question isn't really based on an existing problem with source code but to seek advince/opinions oh a best/better method? – NewToJS Dec 13 '19 at 05:03
  • @NewToJS Sounds like "Is there any disadvantage to X over Y?" It's a fair question, The *existence* of a possible disadvantage isn't opinion-based – CertainPerformance Dec 13 '19 at 05:05
  • It's about when the browser starts to download the script. At end, it'll delay until all HTML content is nearly parsed, and on top, it'll start download immediately when it parses the HEAD tag. If you have a large script file, it may be better to download the script as early as possible. If you also have a large HTML content and put the script at the end of the BODY, you would be delaying the download to complete twice. – Taha Paksu Dec 13 '19 at 05:17
  • If "almost" is good enough for you, maybe you can take into account also http2. Then all that "http/1.1 parallel gotchas" don't have to bother you.. – bigless Dec 13 '19 at 23:40
  • Good to read: https://flaviocopes.com/javascript-async-defer/ – Adam Apr 30 '21 at 10:07
  • 1 Answers1

    1

    You’ve spotted the problem in your last paragraph.

    In terms of JavaScript execution putting defer scripts in head or at bottom has little difference (though it’s different for async scripts). However do be aware that defer scripts execute in order so any other defer script in middle of the page will execute after defer scripts in the head and before defer scripts at the bottom of the page. Usually when using defer you don’t care about the execution time but if there are dependencies then ordering can be important (i.e. loading jQuery before a script that needs jQuery) and defer honours ordering (where as async does not).

    But yes downloads will cause other elements to suffer. Yes the spec recommends two connections are most, but in reality most browsers use 6 connections for HTTP/1.1. This means if your low-priority, defer scripts are using one of those there’s only 5 connections left for everything else on that page. It is likely there are higher priority resources on the page than defer scripts so this is wasteful.

    Browsers will scan ahead in the HTML to get a list of all the resources, and assign a priority to each resource (which will be low for defer scripts) but at the same time the browser will start taking items off the top of this prioritised queue and a low-priority defer script in the head may be started on before the other resources are seen. And because of this “preload scanner”, any benefit of putting defer scripts in the head is minimal. The browser will still see it and request it when it can. Yes it’ll take slightly longer to see it when at the bottom (particularly for large pages that might take a while to fully download) but it’ll still see it as soon as the HTML is downloaded in its entirety, even if it’s still processing scripts and other resources on the page so hasn’t got to the end of the HTML.

    In an HTTP/2 world, where there is not 6-connection limit you may think this doesn’t matter as much, but it often does. Partly because the connection limit is not completely unlimited (100 or 128 parallel streams are common limits on HTTP/2 servers) but more so because bandwidth is not completely unlimited and so download contention is a real thing. HTTP/2 has the concept of prioritisation so in theory should be able to handle this well, but in practice HTTP/2 prioritisation is often poorly implemented on servers and surrounding infrastructure that you can’t depend on this.

    Patrick Meenan has an awesome talk about how browsers load resources, particularly touching on the HTTP/2 issues. Well worth a watch if interested in this sort of thing.

    So, in summary, I would still keep defer scripts to the bottom of the page for now.

    Barry Pollard
    • 40,655
    • 7
    • 76
    • 92
    • I think Google bots also use HTTP/1, and they don't exectue the js, so the first print time will be longer and effect your SEO – Adam Apr 30 '21 at 07:02
    • GoogleBot uses HTTP/2 where supported as of last year (https://developers.google.com/search/blog/2020/09/googlebot-will-soon-speak-http2) and it does execute JS too. – Barry Pollard Apr 30 '21 at 07:09
    • Only selected pages, and the JS loading is also only partially as far as I understood – Adam Apr 30 '21 at 07:16