Script Tag - async & defer
Asked Answered
D

13

819

I have a couple of questions about the attributes async & defer for the <script> tag which to my understanding only works in HTML5 browsers.

One of my sites has two external JavaScript files that currently sit just above the </body> tag; the first is sourced from Google and the second is a local external script.

To site load speed

  1. Is there any advantage in adding async to the two scripts I have at the bottom of the page?

  2. Would there be any advantage in adding the async option to the two scripts and putting them at the top of the page in the <head>?

  3. Would this mean they download as the page loads?

  4. I assume this would cause delays for HTML4 browsers, but would it speed up page load for HTML5 browsers?

Using <script defer src=...

  1. Would loading the two scripts inside <head> with the attribute defer have the same effect as having the scripts before </body>?
  2. Once again I assume this would slow up HTML4 browsers.

Using <script async src=...

If I have two scripts with async enabled

  1. Would they download at the same time?
  2. Or one at a time with the rest of the page?
  3. Does the order of scripts then become a problem? For example, one script depends on the other so if one downloads faster, the second one might not execute correctly, etc.

Finally am I best to leave things as they are until HTML5 is more commonly used?

Delayedaction answered 29/5, 2012 at 23:28 Comment(7)
async is new(ish), but defer has been part of IE since IE4. defer was added to other browsers much more recently, but older versions of those browsers tend to hang around a lot less.Enforce
Now, HTML5 has become very popular!Versicle
defer is same as placing scripts at the bottom of the HTML, which has been common for many years.Dobbins
@Dobbins not necessarily true, the browser will download the JS with the defer tag when it parses the script tag, but will defer exeuction until right before DOMContentLoaded. Downloading is non-blocking. Placing at the bottom of the HTML will delay downloading and execution of the JS until the DOM is constructed, but you will still incur an additional delay by waiting for the download.Homer
@BradFrost - Downloading is blocking in my view, in the sense it is taking internet bandwidth, and for those with slow connection, i see it as imperative to first load the document and only then, when it has been rendered, start downloading javascript files. This is true in cases where the content is not tightly-coupled to javascript for rendering everything (like SPA)Dobbins
@Dobbins I'm just arguing the defer is not the same as placing scripts at the bottom the HTML. When you set it to defer, the browser will download the JS in the background while it continues to construct the DOM. Once the DOM is constructed (DOMContendLoaded fired), the browser will then execute the JS that is has downloaded. That is what I meant by "non-blocking", e.g. it doesn't block the browser from constructing the DOM. This is why it is explicitly marked as defer. The image in an answer below explains it nicely.Homer
Also just to be very clear: defer shouldn't block much of anything, particularly in modern browsers which can at least begin to resolve DNS and then fire off downloads. This is parallel not only to parsing but also to other downloads. This includes multiple requests to the same server, or to different servers and particularly when you also account for HTTP/2 (capable of automatically and efficiently multiplexing requests over the same connection).Blasphemy
G
477

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.

Generalization answered 29/5, 2012 at 23:45 Comment(16)
and what if I have only one big minifed script in order?Kharif
@IdanShechter, that's bad for caching.Kalk
Defer should run them in order still, but run before dom-contentloaded. Doesn't that mean putting it in head would be faster, since it can start downloading them BEFORE The body html is parsed?Irishirishism
@Irishirishism - faster to what? If the goal is fastest time to first page display, then putting deferred scripts in the <head> section can only slow that down (more things to parse and more things to use network bandwidth loading before the page displays) vs. putting them at the end of the <body> section. If the goal is fastest time until the deferred scripts run, then yes they might get loaded faster if they were put in the <head> section, but that isn't the question that I was trying to answer of that I thought was being asked.Generalization
But if there are many scripts without defer right before </body>, then looks like browser should download them one-by-one. But if they have defer attribute, then browser could download them in parallel: faster.Idem
@DzmitryLazerka - There is a difference between downloading and execution. Some browsers will download scripts in parallel (as a performance optimization), even if they don't have the defer attribute, but it will only parse and run them in the prescribed order.Generalization
You said putting scripts in head and setting them to defer won't be any faster than putting them before </body>, but from what I've read that is incorrect. Think about it -- if you put the scripts in <head>, then they will start downloading immediately, whereas if they are right before </body> then all the other elements download first.Smattering
@Smattering - It won't make your document load any faster which is my point. You are correct that it could improve loading the script sooner, but it also could slow down loading of the document and it's contents because you're using some of your bandwidth and using one of the limited connections the browser will make to a given server to load the script while it's also trying to load your content.Generalization
"If your second script depends upon the first script... then you can't make them either async or defer" -- that's not true, with defer they execute in order.Henriques
@Henriques - corrected. Detailed execution rules are spelled out here: #8997352. Deferred scripts will still execute in the order encountered, just not until after the document has been parsed.Generalization
defer will make a difference because it only waits for DOM parsing. Without it it will also wait for style to be downloaded and applied. (tested with FF 44, Chrome 26). So don't be surprised that $('body').css('height') will return an other value if u use defer.Seedbed
WARNING: defer does not work properly in <= IE9. See github.com/h5bp/lazyweb-requests/issues/42Sacha
Scripts that are defered have the added bonus of not needing to wait for DOMContentLoaded (or jQuery.ready, etc...) since they run after DOM parsing.Grannia
At this point, the </body> requirement isn't really necessary with browser developments since 2012 when this answer was posted.Snowwhite
I assume defer and async are pointless for a dynamically loaded script? (i.e. document.createElement('script'); ...)Ovalle
@Ovalle - I suppose if the document.createElement() is inline in the page's Javascript, then defer and async could affect it (though it isn't something I've researched). But, if the page is already fully loaded, I wouldn't think they would have much of an effect.Generalization
F
1377

This image explains normal script tag, async and defer

no attribute vs async vs 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 guarantee the order of execution in which they appear in the page.

Ref this link: async vs defer attributes - Growing with the web

Felike answered 26/9, 2016 at 19:37 Comment(9)
I think an example with multiple scripts would have been better to illustrate their sequenceDobbins
@writofmandamus Looks like async will win. See #13821651Bullwhip
Thanks for the good explanation. However, the images are not to scale. In case of only the <script> tag, the total length of page load is longer by the time it takes to download the script file.Spurn
@BhavikHirani According to this site, using both async and defer in the same script tag uses async if the browser supports it, or falls back to defer if it doesn't support async, but supports defer. The behaviours are pretty different, so I would not advise using both, as the outcome is unpredictable and can be a great source for bugs.Dilate
@Spurn Only if the bandwidth is fully utilized, which it seldom is. And both downloads would share the bandwidth, not block one.—Further: these images show parsing in green, not download.Trend
If you don't put async or defer it will still load in that order.Chloramphenicol
@RobertSiemer you didnot really understand what arni means. Arni - yes in the first part with only the script tag, the green line should be longer (as long as the grey line). Otherwise you dont really see why the first option is actually worse than others.Wersh
That really helped me to understand better.Hunterhunting
@JustinLiu (my addition) similar to the normal script tag.Sturmabteilung
G
477

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.

Generalization answered 29/5, 2012 at 23:45 Comment(16)
and what if I have only one big minifed script in order?Kharif
@IdanShechter, that's bad for caching.Kalk
Defer should run them in order still, but run before dom-contentloaded. Doesn't that mean putting it in head would be faster, since it can start downloading them BEFORE The body html is parsed?Irishirishism
@Irishirishism - faster to what? If the goal is fastest time to first page display, then putting deferred scripts in the <head> section can only slow that down (more things to parse and more things to use network bandwidth loading before the page displays) vs. putting them at the end of the <body> section. If the goal is fastest time until the deferred scripts run, then yes they might get loaded faster if they were put in the <head> section, but that isn't the question that I was trying to answer of that I thought was being asked.Generalization
But if there are many scripts without defer right before </body>, then looks like browser should download them one-by-one. But if they have defer attribute, then browser could download them in parallel: faster.Idem
@DzmitryLazerka - There is a difference between downloading and execution. Some browsers will download scripts in parallel (as a performance optimization), even if they don't have the defer attribute, but it will only parse and run them in the prescribed order.Generalization
You said putting scripts in head and setting them to defer won't be any faster than putting them before </body>, but from what I've read that is incorrect. Think about it -- if you put the scripts in <head>, then they will start downloading immediately, whereas if they are right before </body> then all the other elements download first.Smattering
@Smattering - It won't make your document load any faster which is my point. You are correct that it could improve loading the script sooner, but it also could slow down loading of the document and it's contents because you're using some of your bandwidth and using one of the limited connections the browser will make to a given server to load the script while it's also trying to load your content.Generalization
"If your second script depends upon the first script... then you can't make them either async or defer" -- that's not true, with defer they execute in order.Henriques
@Henriques - corrected. Detailed execution rules are spelled out here: #8997352. Deferred scripts will still execute in the order encountered, just not until after the document has been parsed.Generalization
defer will make a difference because it only waits for DOM parsing. Without it it will also wait for style to be downloaded and applied. (tested with FF 44, Chrome 26). So don't be surprised that $('body').css('height') will return an other value if u use defer.Seedbed
WARNING: defer does not work properly in <= IE9. See github.com/h5bp/lazyweb-requests/issues/42Sacha
Scripts that are defered have the added bonus of not needing to wait for DOMContentLoaded (or jQuery.ready, etc...) since they run after DOM parsing.Grannia
At this point, the </body> requirement isn't really necessary with browser developments since 2012 when this answer was posted.Snowwhite
I assume defer and async are pointless for a dynamically loaded script? (i.e. document.createElement('script'); ...)Ovalle
@Ovalle - I suppose if the document.createElement() is inline in the page's Javascript, then defer and async could affect it (though it isn't something I've researched). But, if the page is already fully loaded, I wouldn't think they would have much of an effect.Generalization
E
263

HTML5: async, defer

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

<script       src="myscript.js"></script> // 1

<script async src="myscript.js"></script> // 2

<script defer src="myscript.js"></script> // 3
  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.)

Eyeshot answered 24/10, 2013 at 3:47 Comment(4)
blogger.com template required async="" before it would validate and save template changes.Gabble
Note: there is no guarantee that scripts will run in the order they are specified using Async. "So if your second script depends upon first script avoid Async."Pigeonwing
async - Scripts are executed the moment they have been downloaded, with no consideration to their order in the HTML file.Dobbins
True, I believe this is the case.Diaz
W
48

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.

Wootan answered 12/6, 2014 at 11:30 Comment(2)
I am actually amazed that no other answer mentions the order of DOMContentLoaded yet... That's super crucial information. Also amazingly enough, this is not mentioned on the script tag page, but it is here: developer.mozilla.org/en-US/docs/Web/API/Document/…Icebox
...if anyone wonders why, it's because DOMContentLoaded !== jQuery.ready(), aka it's only fired ever once. So it would stop working with defer, but defer is guaranteed to be sooner so it doesn't :-)Icebox
F
41

Faced same kind of problem and now clearly understood how both will works.Hope this reference link will be helpful...

Async

When you add the async attribute to your script tag, the fol­low­ing will happen.

<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>
  1. Make par­al­lel requests to fetch the files.
  2. Con­tinue pars­ing the doc­u­ment as if it was never interrupted.
  3. Exe­cute the indi­vid­ual scripts the moment the files are downloaded.

Defer

Defer is very sim­i­lar to async with one major dif­fer­er­ence. Here’s what hap­pens when a browser encoun­ters a script with the defer attribute.

<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
  1. Make par­al­lel requests to fetch the indi­vid­ual files.
  2. Con­tinue pars­ing the doc­u­ment as if it was never interrupted.
  3. Fin­ish pars­ing the doc­u­ment even if the script files have downloaded.
  4. Exe­cute each script in the order they were encoun­tered in the document.

Reference :Difference between Async and Defer

Fortuitism answered 12/10, 2016 at 7:16 Comment(0)
C
29

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 doesn'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 <script defer>.

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

Casket answered 23/2, 2015 at 1:25 Comment(4)
Just want to make some clarification here, two things are happening here 1. Downloading of resource 2. Execution of resource. Downloading of resource in both cases(async and defer) are not blocking, means, they don't block the parsing of html, while execution in async blocks the parsing and in case of defer, execution takes place after the html markup is parsed, hence non blocking in this case.Hangeron
@Hangeron Since requesting and downloading resources are done by http request thread,which is executed In parallel with GUI render thread,they will not block the parsing of html,right?However,js engine thread and GUI render thread are mutually exclusive.So when js engine thread executes js code,the GUI render thread which parses html will be blocked.Marjoram
Both will not interrupt the parser. this thing is wrong, the parsing would be blocked in case of asyncPrier
defer is superior to putting scripts at the end of the HTML because the browser may start fetching them earlier if it has free resources.Scaremonger
D
20

Good practice is to keep all the files in your source folder to load source files fast. You need to download all the script, style, icon, and image-related files and put these files into your project folder.

Create these folders in your project to keep different source files and then load the required files into the pages from these folder.

js: to keep script-related files.

css: to keep style-related files.

images: to keep image/icon-related files

fonts: to keep font-related files


When to use defer and async attributes on the <script> tag

defer attribute: First the defer attribute will download the script file and then wait for HTML parsing. After the end of the HTML parsing, the script will execute. In other words, it will guarantee all the scripts will execute after the HTML parsing.

The defer attribute is useful when the script is used for DOM manipulations.

async attribute: The async attribute will download the script file and execute without waiting for the end of HTML parsing. In other words, it does not guarantee that all the scripts will execute after the HTML parsing.

The async attribute is useful when the script is not used for DOM manipulation. Sometimes you need a script only for server-side operations or for handling cache or cookies, but not for DOM manipulations.

enter image description here


Useful link when to use defer and async: https://mcmap.net/q/48034/-can-you-use-both-the-async-and-defer-attributes-on-a-html-tag

Digital answered 27/8, 2021 at 18:37 Comment(2)
growingwiththeweb.com/2014/02/…Ploughshare
For scripts and other resources that are unique to your site, this is a good plan. However, for common libraries like jQuery or FontAwesome, I was under the impression that its better to use a CDN, as browsers may have already cached some of those libraries, and therefore would be able to skip fetching them again. Is this correct?Simeon
K
6

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.

Knott answered 13/8, 2019 at 21:41 Comment(0)
F
4

Rendering engine goes several steps till it paints anything on the screen.

it looks like this:

  1. Converting HTML bytes to characters depending on encoding we set to the document;
  2. Tokens are created according to characters. Tokens mean analyze characters and specify opening tangs and nested tags;
  3. From tokens separated nodes are created. they are objects and according to information delivered from tokenization process, engine creates objects which includes all necessary information about each node;
  4. after that DOM is created. DOM is tree data structure and represents whole hierarchy and information about relationship and specification of tags;

The same process goes to CSS. for CSS rendering engine creates different/separated data structure for CSS but it's called CSSOM (CSS Object Model)

Browser works only with Object models so it needs to know all information about DOM and CSSDOM.

The next step is combining somehow DOM and CSSOM. because without CSSOM browser do not know how to style each element during rendering process.

All information above means that, anything you provide in your html (javascript, css ) browser will pause DOM construction process. If you are familiar with event loop, there is simple rule how event loop executes tasks:

  1. Execute macro tasks;
  2. execute micro tasks;
  3. Rendering;

So when you provide Javascript file, browser do not know what JS code is going to do and stops all DOM construction process and Javascript interptreter starts parsing and executing Javascript code.

Even you provide Javascript in the end of body tag, Browser will proceed all above steps to HTML and CSS but except rendering. it will find out Script tag and will stop until JS is done.

But HTML provided two additional options for script tag: async and defer.

Async - means execute code when it is downloaded and do not block DOM construction during downloading process.

Defer - means execute code after it's downloaded and browser finished DOM construction and rendering process.

Formalism answered 5/1, 2021 at 13:28 Comment(0)
U
2
  1. Default - By default, as soon as the browser sees a script tag it downloads the file and then executes the script file. The script files are executed in the order of their occurrence.

  2. async - The browser will download the script file and continue parsing HTML parallelly until the file is downloaded. The file is executed as soon as it is downloaded.

  3. defer - The browser will download the script and do HTML parsing at the same time. After parsing is done, the script files are executed in the order of their occurrence.

Note: In defer, the js files are executed in the order of their occurrence in the HTML file while in the case of the async attribute the script files are executed in the order of download time.

Uphemia answered 18/12, 2022 at 17:3 Comment(0)
C
1

It seems the behavior of defer and async is browser dependent, at least on the execution phase. NOTE, defer only applies to external scripts. I'm assuming async follows same pattern.

In IE 11 and below, the order seems to be like this:

  • async (could partially execute while page loading)
  • none (could execute while page loading)
  • defer (executes after page loaded, all defer in order of placement in file)

In Edge, Webkit, etc, the async attribute seems to be either ignored or placed at the end:

  • data-pagespeed-no-defer (executes before any other scripts, while page is loading)
  • none (could execute while page is loading)
  • defer (waits until DOM loaded, all defer in order of placement in file)
  • async (seems to wait until DOM loaded)

In newer browsers, the data-pagespeed-no-defer attribute runs before any other external scripts. This is for scripts that don't depend on the DOM.

NOTE: Use defer when you need an explicit order of execution of your external scripts. This tells the browser to execute all deferred scripts in order of placement in the file.

ASIDE: The size of the external javascripts did matter when loading...but had no effect on the order of execution.

If you're worried about the performance of your scripts, you may want to consider minification or simply loading them dynamically with an XMLHttpRequest.

Claypoole answered 28/7, 2017 at 2:1 Comment(1)
data-pagespeed-no-defer is an attribute used by the server side PageSpeed module. The data-pagespeed-no-defer attribute by it self has no effect in any browser.Spool
S
0

For those who are in Nextjs and using Theme provided by the nextjs, the problem could occur if you are using theme Provider component outside the body tag. Simply, enslose the theme provider component inside the body tag to get the problem fixed:

Your layout.js ordering should look like this where theme provider is inside the body tag:

import "./globals.css";
import TProvider from "@/context/ThemeProvider";
import Header from "@/components/common/Header";
import Footer from "@/components/common/Footer";

const RootLayout = function ({ children }) {
  return (
    <html lang="en">
      <body>
          <TProvider>
            <Header />
              <main>
              {children}
              </main>
            <Footer />
          </TProvider>
      </body>
    </html>
  );
};

export default RootLayout;
Selachian answered 29/11, 2023 at 7:25 Comment(0)
S
-1

Async is suitable if your script doesn’t contains DOM manipulation and other scripts doesn’t depend upon on this. Eg: bootstrap cdn,jquery

Defer is suitable if your script contains DOM manipulation and other scripts depend upon on this.

Eg: <script src=”createfirst.js”> //let this will create element <script src=”showfirst.js”> //after createfirst create element it will show that.

Thus make it: Eg: <script defer src=”createfirst.js”> //let this will create element <script defer src=”showfirst.js”> //after createfirst create element it will

This will execute scripts in order.

But if i made: Eg: <script async src=”createfirst.js”> //let this will create element <script defer src=”showfirst.js”> //after createfirst create element it will

Then, this code might result unexpected results. Coz: if html parser access createfirst script.It won’t stop DOM creation and starts downloading code from src .Once src got resolved/code got downloaded, it will execute immediately parallel with DOM.

What if showfirst.js execute first than createfirst.js.This might be possible if createfirst takes long time (Assume after DOM parsing finished).Then, showfirst will execute immediately.

Siena answered 28/1, 2021 at 11:24 Comment(1)
Your statement isn't correct. Async script is very much suitable for DOM manipulation and other scripts may depend on it. You have to be aware of how async works, or use async modules. As a simple example async #1 can be used to create certain elements (Ajax call for example). async #2 can be used to add an event to already present button that does something to data fetched by async #1 if present.Make

© 2022 - 2024 — McMap. All rights reserved.