3
<head>
<script src="1.js"></script> 
</head>

<body>
<script src="3.js"></script>
</body>
//js1.js
let head = document.querySelector('head'); 
let script = document.createElement('script');
script.src = '../js/js2.js';
script.async = false;
head.append(script);

console.log(1);
//js2.js
console.log(2);
//js3.js
console.log(3);

The order I got in my browser was: 1, 3, 2. I expected 1, 2, 3 because 1.js puts the script that executes 2.js immediately below it and 3.js only executes at the end of body. I was under the impression i) in dynamic scripts, loading starts as soon as the script is appended to the DOM (and presumably execution will follow).

Is the reason why js.3 gets executed last got something to do with a rule that says dynamic script tags aren't executed during the 'initial parsing of the html'?


enter image description here

tonitone120
  • 1,920
  • 3
  • 8
  • 25
  • 1
    the response is in here `dynamic scripts have async attribute by default (and therefore execute as soon as they're loaded).` . that script has to be loaded; in the meantime, the parsing of the HTML continues, and `js3.js` executes. Once the `js2` finishes loading, it gets executed – Gonzalo.- Sep 07 '20 at 01:44
  • @Gonzalo.- I totally forgot that thank-you. However, even when I set `async` to false (`script.async = false`) I still get the 132 output (I've updated the question to include that now). – tonitone120 Sep 07 '20 at 01:47
  • 1
    how do you make async on false? – Mister Jojo Sep 07 '20 at 01:49
  • @MisterJojo `script.async = false` – tonitone120 Sep 07 '20 at 01:51
  • @MisterJojo Really? It seems to work when I inspect the script element (I will put a picture at bottom of post) and was demonstrated in a tutorial I read – tonitone120 Sep 07 '20 at 01:54
  • 1
    The `append` is still async. Here is a solution: https://stackoverflow.com/questions/3248384/document-createelementscript-synchronously – GAEfan Sep 07 '20 at 01:54
  • probably in order to be able to `append` the script, it has to finish parsing the whole HTML, then modifying the DOM and updating it. But it's a guess – Gonzalo.- Sep 07 '20 at 01:57
  • I didn't find any where this syntax , async can't be set to false – Mister Jojo Sep 07 '20 at 01:57
  • @MisterJojo Have you seen the picture I've posted? – tonitone120 Sep 07 '20 at 02:01
  • @GAEfan I didn't find a solution in that post. If the solution was the `onload` event listener, that didn't do it – tonitone120 Sep 07 '20 at 02:02
  • what ever the picture code you posted, this is more about the browser's loader question than any DOM assignments. Your assignment will always happen after the loader execution, which automatically start the script execution. your command happen when everything is done – Mister Jojo Sep 07 '20 at 02:07
  • @MisterJojo I don't know what you mean when you say: loader question and loader execution. Are you saying the `.append` line is only executed (or something to the effect of 'the dynamic script is only executed') after the 'initial parsing of `.html`'? – tonitone120 Sep 07 '20 at 02:12
  • @Gonzalo.- I suspect we'd never want to create a dynamic script during 'initial parsing of html' anyway. What’re your thoughts about this? – tonitone120 Sep 07 '20 at 02:16
  • 2
    Dynamically inserted script elements *always* load asynchronously. Setting `async = false` doesn't change that. If you absolutely needed to dynamically insert a synchronous script, you'd have to use `document.write` as in the answers that GAEfan linked. – Bergi Sep 07 '20 at 02:16
  • on any system, to start any application, there is first a loader action. In a browser, this works in a different world than the one belonging to the DOM as defined by the W3C – Mister Jojo Sep 07 '20 at 02:20
  • Thanks @Bergi. I've understood asynchronously to mean: its placed in a 'WebAPI' section and when loaded, the task can enter a macro (or micro) -task queue. When you say asynchronous here it must mean something different because I'm sure the dynamic script would find its way to the front of the macro-task queue (and onto the call-stack) before `3.js` would. In this context, when you say asynchronously, do you mean after 'initial parsing of html'? Or do I lack understanding of how scripts are executed (I thought scripts were macro-tasks that pushed onto the call-stack (and pushed off) one by one – tonitone120 Sep 07 '20 at 02:24
  • Maybe I should have said "blocking" and "non-blocking". Some scripts are blocking the HTML parser (stop it from building the DOM until they are executed), some don't. – Bergi Sep 07 '20 at 02:30
  • "*I'm sure the dynamic script would find its way to the front of the macro-task queue (and onto the call-stack) before 3.js would*" - why? Maybe it's taking longer to load *2.js* than to load *3.js* (especially if the browser uses lookahead and prefetching). – Bergi Sep 07 '20 at 02:32
  • @Bergi So dynamic scripts are non-blocking (hope I've got that right). That is to say, they only loads (and executes) after the HTML parser (what I've clumsily been calling 'initial parsing of HTML')? – tonitone120 Sep 07 '20 at 02:38
  • @tonitone120 They load as soon as the are inserted into the DOM, and afaik will (be scheduled to) execute as soon as they are loaded. This might even happen while the HTML is still being parsed. – Bergi Sep 07 '20 at 03:11
  • @Bergi In that case the question is why `js.2` took longer to load than `js.3` right? You mentioned some things concerning that. What's the meaning of the word asynchronous here though? Aren't all scripts asynchronous in that they're put in the queue when they're loaded and then pushed to the call-stack to execute when the call-stack's empty? I'm not sure why you mentioned that 'blocking' 'non-blocking' thing if dynamic scripts don't behave differently to a regular script and will indeed do 'blocking' – tonitone120 Sep 07 '20 at 03:33

0 Answers0