It sounds to me that you might be confused by what the "async" loading does.
All HTML and scripts (including dynamically inserted scripts like in your case) parse and execute in a single thread.
However, fetching (meaning downloading from the web) can be done at the same time as the above thread. The browser will continue fetching external files (CSS, scripts, images, etc.) in parallel. But in the case of scripts, it will pause parsing when it reaches a script tag that is not fully fetched yet, and execute the script once fetched, so that the script has a chance to modify the rest of the page before the browser parses it. You can change that behaviour using async
and defer
attributes in your script tag. The just described behaviour corresponds to the default values async = false
and defer = false
.
When async == true
, the browser will continue parsing the page while fetching the script in parallel, then pause the parsing when fetch is completed (hence this can happen at any point in parsing the page), and execute the script. Here you can see the effect of the single thread. I think the spec has a good figure to illustrate that.
Now in the case of dynamically inserted scripts like in your case, most browsers will use async = true
by default. Refer to that post and MDN notes for further details.
Finally, there is another meaning when referring to "asynchronous" loading: AMD (if you use Require.js for example) typically uses the code that you show to insert script tags dynamically. In this context, the asynchronous is more about the ability to fetch and execute different scripts "on demand", i.e. only when the user requests some extra functionalities (for example you open a form edition, so the page will only fetch and execute the script related to editing at that moment).