Hi everyone! I hope youβre doing good. This article will explore an interesting Javascript topic. async and defer are attributes used when includin...
For further actions, you may consider blocking this person and/or reporting abuse
As far as I know modern browsers use a preload scanner, so they start loading all scripts before HTML is parsed.
Anyway, things get interesting with ES6-modules that depend on other modules. I suppose it would make sense to put those dependencies in the head of your HTML file, even if they are not needed in the main context?
If you use a framework (or have enough patience using bundlers to customize uour own stuff) they manage "chunks" so each "route" gets what it needs and nothing else. It's possible to dynamically import stuff as well (e.g. Next/dynamic in Next JS as example, you can find vanilla examples online for that as well).
When loading scripts in HTML one can also create the script (html tag) dynamically and inject it to the DOM using the classic "appendchild" approach, meaning that you can have them load "on demand".
As @efpage well said, modern browsers have a preload scanner, the post don't fight the browser preload scanner is worth reading.
PD: you can manually add preload link tags for older browsers to use or to control the preload for different reasons.
Lastly and regarding the conclusions, it usually doesn't really matter that much which one you choose because both achieve the goal of not blocking the process, and you should wait for window load event (so everything has loaded) anyway shall you require it in tour scripts.
Cheers!
With Web Components (eg:
<my-component
) it does matter because the nativeconnectedCallback
fires on the opening tag. Not usingasync
ordefer
could be a better choiceDev.to post: Web Component developers do not connect with the connectedCallback (yet)
The topic seems to be quite conplex, so I would tend to choose the most simple and robust approach. Just.... what are the consequences?
Fetching scripts and possibly executing them early could make your app feel more "snappy" and responsive, though in most cases I suppose the differences will be in the range of 200 ms or so, but the more important thing for me: Will it be recognized by the user?
ItΒ΄s worth to recap what a browser really does behind the scenes. See this great post on logrocket. Building the DOM is only one step, but there are multiple steps to be done, before a page is rendered. So, anything done before first render may delay the FCP, but will lead to a consistent result.
But what happens, if you wait for
DOMContentLoaded
? Will actions done in the event it still be included in the first render cycle, or will it cause a new one? If the content changes, you will possibly get a layour shift, so the content is rendered and just rerendered with a different layout, which looks not great.IΒ΄m really not sure how to deal with this topic, expecially on large sites.
A complex topic indeed. I'd analyse each use-case individually as there is no golden rule here, profile your large app so you can see what is blocking you. I've seen companies spending monies in thousands trying to optimise the wrong thing.
@dannyengelman using web components you need to first introduce an unknown tag into the DOM just to tell the browser what it is afterwards.
If you analyse it, it's no different than creating and injecting an HTML tag into the DOM from a script, or adding some feature to a given selected HTMLElement.
By that I mean that you are in control of this "afterwards" just like in any other script; you can also use async/defer and inside your script, wait for the proper event, then define your web component/s, and the result would be the same I assume.
You are wrong here; you can use
customElements.define
before DOM is parsed.This can easily be checked with
element instanceOf HTMLElement
Its just that 89 out of a 100 developers do not know/do this. They fall into the connectedCallback trap and never investigate WHY their code doesn't work, and whack on
async
ordefer
thinking they solved the problem.So Web Components are totally different from (oldskool) create-DOM-after-DOM-is-parsed scripts.
Note: 1. can be two stages, like with icons: define the GUI ASAP, add interactivity later
This just means that the code is available in the DOM. I suppose it will be executed when HTML is parsed which is not much different from executing a script somewhere inmiddle of your HTML code.
Anyway, this could be an advantage as HTML expression is usually paused as long as scripts are executed, but I suppose the differences will be minor.
Difference is major when GUI Web Components are created with render blocking and inlined
<script>
in the<head>
; then get enhanced to full interactive GUI afterDOMContentLoaded
Inline the GUI required CSS as well (I mean bare CSS, not Tailwind) and the first HTML page should be 10 to 15 KB at the most... Eat that Vue,React.
I suppose, Tailwind (or any CSS in JS solution) will give another twist to this story, but this possibly would fill a complete post. Anyway, an interesting story...
I said not to use Tailwind. That's a 479 Kb Gzipped download.
Do everything (for your primary GUI) native and in one HTML file, then PWA
Sorry this was a misunderstanding. Even if you do not use a bulky package like tailwind, any JS that manipulates global CSS might cause strange effects like Layout shifts and unexpected delays. But this would fill another post I suppose.
Thanks for sharing! Really insightful!!
Use qwik.
This will do all the right things with the js.
I find the article misleading because it's not "vs". You can use both
defer
andasync
together, they don't exclude each other since they are unrelated. Defer is to wait for the page dom first, async is when other scripts don't need to wait for it.Thanks for the visual differences. it easy to understand. I really appreciate
Nice One Bro!
Pictures are nice. One should also know that browser does much more behind the scenes, that v8/gecko is single threaded but it's i/o is multithreaded, and lastly the impact onto the server (and how many requests can be done in parallel). Next step is http/2.0 multiplexing, tcp/IP topics (but also quic over tcp/udp), load balancing, cdn, cookies and serverside sessions, race conditions and effects if not done correctly. That is where the fun and complex stuff starts :)
Great article though for less experienced front-end devs :)
This article is a great overview. For a deeper dive, particularly into the
DOMContentLoaded
event check out this article:javascript.info/script-async-defer
terimakasih atas ilmunya, saya baru mengetahui adanya defer.
Informative :)
It is a mind-blowing article because I don't know about deferring previously. From there I understand the difference and also when I need to use deffer and async.
Thanks a lot.
How to do same in react?