If you work in a frontend project like React, it is highly likely that you may need to add some scripts on the website. And you know that we can simply use the HTML <script>
element to embed executable code or data. But how to do it effectively?
Ideally, we’d like to load the scripts asynchronously, aka. in a non-blocking manner. What we can use the async
and defer
attributes on the script tag as per the MDN Doc says:
async
: If the async
attribute is present, then the script will be fetched in parallel to parsing and evaluated as soon as it is available.
defer
: Similar to async
, this Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded
. Scripts with the defer
attribute will execute in the order in which they appear in the document.
Both attributes allow the elimination of parser-blocking JavaScript where the browser would have to load and evaluate scripts before continuing to parse. And note that
And the differences are :
- async : The orders don’t matter, as each async script loads independently. It executes whenever it is loaded and parsed.
- defer: Each defer script loads according to the document order. It executes after the document is loaded and parsed, but right before
DOMContentLoaded
. Note thatdefer
is ignored if it’s an inline script, aka. a<script>
tag has nosrc
.
So while both can be used for non-blocking script loading, in general, defer
is used for scripts that need the DOM content or their execution order needs to be maintained. And async
is used for third party scripts that is not dependent on the DOM content and the execution order does notThis can be changed if we explicitly set script.async=false
. Then scripts will be executed in the document order, just like defer
.
But how is everything coming together in a React?
We normally create script dynamically and append it to the Document body.
Note that scripts created this way is async
by default.
import React from "react";
interface IThirdPartyProps {
id: string;
}
export const loadScript = () => {
const script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://third-party-script.js";
script.id = "third-party-script-async";
document.head.appendChild(script);
};
const ThirdPartyScript: React.FC<IThirdPartyProps> = props => {
if (typeof window === "undefined") {
return null;
}
if (document.getElementById("third-party-script-async") === null) {
loadScript();
}
return (
<div
data-id={props.thirdPartyId}
data-type="interactive"
/>
);
};
export { ThirdPartyScript };
That’s pretty much it!
Thanks for reading!