Any good reason not to use <script defer> TODAY?
Asked Answered
P

2

31

Once upon a time, there were many heated debate on <script> in <head> or <body>.

Many SO posts had already pointed out the best practice / rule of thumb is to place the <script> before end of <body>for not blocking the html parser, resulting faster first screen paint and quicker DOM access for client, and thus a better UX.

This must be a duplicate╰(‵□′)╯

Wait ... <script> can be deferred now, actually for quite a while !

Old posts said

deferred script may results JS dependency issues

No, it won't. It retains the order on execution immediately when the DOM gets parsed.

It doesn't work cross vendors

Yes, it once was, but today it's almost supported by all major browser vendors: http://caniuse.com/#search=defer, besides may have some problem with IE<10 as the comments point out.

However, the benefits it offers seem obvious, at least to me, as it downloads the script in parallel at earlier time(before start parsing the DOM), thus no need to request the script later and shortens the time it takes to bring the whole page interactive.

To be short, this question is similar to: Any good reason not to use

<head>
...
<script src='cdn/to/jquery' defer>
<script src='cdn/to/bootstrap' defer>
<script src='script/depends/on/jqueryandbootstrap' defer>
</head>

instead using this:

<body>
...
<script src='cdn/to/jquery'>
<script src='cdn/to/bootstrap'>
<script src='script/depends/on/jqueryandbootstrap'>
</body>

note: This might be an "ancient" topic with lots of discussions. However, as web technology moves really fast, browser vendors align better and more consistent with new web specs, many old stackoverflow answers may not keep up-to-date.

Pulsar answered 1/3, 2017 at 22:57 Comment(11)
there's a note in caniuse that IE < 10 could be broken - in my opinion, that's a good reason to start using defer now :pOverview
Here is some good reading.Leucine
@Leucine I've seen that, that's a good visualize, besides i think both async and defer should take less time in total.Pulsar
async is the one that can cause dependency issues. You can use defer, if the browser doesn't support it, it may take a little longer to load but it won't break the page.Gaelan
@Gaelan Does this mean, for browsers don't support defer, the fallback will be the same as put script before end of body.Pulsar
Possible duplicate of Script Tag - async & deferHagio
it will be the same as putting it in the head of head without deferGaelan
@JayHarris I come to this from the post you listed, you can read the accepted answer, as it still suggest to use script before end of body, i'm trying to figure out why here. One of the main reason it gives is the old browser problems which i've already pointed out in the post.Pulsar
I nearly forgot this(defer) magic attribute; This is an interesting article I found on Mozilla HackWeevily
would defer remove the need for $(document).ready()?Abstract
As per the following article, nowadays, it not so important to use defer as long as you put your script at the end of the page: blog.dareboost.com/en/2017/12/…Luftwaffe
P
10

Yes, but only because you're using jQuery.

jQuery doesn't work with defer because it tries to fire as soon as the page becomes interactive. They can't fix it any time soon (I raised that bug over a year ago) because changing the ready behaviour to work with defer will break lots of components that rely on jQuery's ready event firing on interactive (i.e. before deferred scripts have finished loading).

If you're using a more modern framework (React, Angular 2, Polymer, Vue, or just about anything else) then go for it - or even go to the next step and use <script type=module in new browsers and a legacy bundle in <script nomodule defer... for IE.

Panlogism answered 18/10, 2017 at 15:40 Comment(7)
To be clear, its OK to use defer to load any other JS library even if I am using jQuery in my project, I just can't use defer to load the jQuery library. Is that right?Kutzenco
@Kutzenco you can defer anything else you want, but you can't rely on jQuery having loaded or the loaded event. jQuery and everything that depends on is must be synchronous. It's not only jQuery - any library that tries to hook the DOM load event may have the issue, there was a bit of a trend for trying to jump the DOM loaded event in libraries from that period.Panlogism
As a concrete example, I am following Google's map API example here: developers.google.com/maps/documentation/javascript/tutorial They are using async and defer and they are also putting the script tag at the bottom. Is that best practice now days?Kutzenco
@Kutzenco no, Google's map API is actually kind of awful - it's great for 2009, but full of hacks for deprecated IE6 and the like. It doesn't work with shadow DOM and memory leaks in an SPA. Best practice is type=module with a nomodule fallback, or use dynamic imports.Panlogism
@Kutzenco but, you can totally use it on a page with jQuery and follow that example and it will work. Just not in an SPA.Panlogism
This is quite an old question, but still giving it a try: I'm a bit confused, can I use defer on my other custom javascript file, if I am also using jQuery commands in that file? As I understand I just cant use defer attribute near the jQuery inclusion in html, but I can use the defer on another script even tho it uses jQuery? Or is it just only if I am not using jQuery, then I can defer everything else?Dragrope
@Dragrope jQuery is all about the $(function) that fires on ready, use that or any jQuery plugin that depends on it, and you don't know in any defer script whether it has fired yet or not. If you want to use jQuery or any dependency in a file you can't defer it reliably (though it might work sometimes based on loading times), but you could keep the jQuery stuff inline and the newer stuff in defer scripts. However, then the question becomes why bother with jQuery at all? jQuery is fine and stable in old apps where you haven't used defer, I'd avoid it in any new development now.Panlogism
R
0

As noted here you should take browser support into account, as some of them don't really support it. There are also some well known bugs in some versions like this one in IE<=9.

If your goal is not to support old browsers (find full support list here) then there is no real reason for not picking defer today.

Rigmarole answered 24/10, 2020 at 10:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.