Async script loading is what i'm learning now. I have a question about async attr in script tag - <script async src="...">.
here is some info, http://www.w3schools.com/tags/att_script_async.asp and my question is about this - When present, it specifies that the script will be executed asynchronously as soon as it is available. line.
Question:
If i have 2 scripts:
<script async src="url1.js"><script> // 200kb
<script async src="url2.js"><script> // 2kb
and the second script must be executed AFTER first (it uses some Objects or functions from it) - will it be so after page load? will first script execute first after loading, and then - the second, or not?
From bold string above - I understand it so, that than faster the script was loaded - the faster it will be executed, and in our example we will have errors, while first script wasn't loaded and executed yet, but second is already trying to get it. (and when we can use async script loading? only when our scripts are not independent of each other?)
p.s. is lazy loading script the only way to get the correct script execution order in this case - to prevent errors?
Without the async attribute, the browser will stop processing the page and first download the referenced script; once the script is downloaded and executed it will continue processing the next tag on the page. This has two consequences:
All scripts are guaranteed to load in the order they're included in the HTML, and dependencies are guaranteed to resolve correctly.
The page loading is noticeably delayed, if those scripts are included early. Synchronous scripts should always be included at the end of the page to not leave the visitor waiting needlessly.
If you set the async attribute, the browser will continue loading the page without stopping to process the script tag, and will load the script sometime later. When exactly the script is loaded is undefined and you cannot depend on any particular order of execution. If you have dependencies between two scripts, you cannot load them asynchronously, because then it's down to pure luck whether one will load before the other.
As such, async loading is only useful for scripts which have no other dependencies. Or: you hook your scripts to the window.onload event and avoid making any cross references before then; the event will be fired after all scripts have loaded, including async scripts.
If url2.js depends on url1.js you cannot use async loading for script files you must use synchronous (eager loading) to ensure that url1.js is loaded and executed before url2.js.
Using async two cases can occur:
url1.js loads and executes then url2.js loads and executes. This is okay as url1 will be ready for url2.
url2.js loads and executes then url1.js loads and executes. This will fail as url2 depends on url1 which is not ready at the time url2 is.
Using non-async loading only one case can occur, which is url1.js loading and executing before url2.js loads and executes which is what you need if they depend on each other.
In async loading you can't control when they are executed, they execute as soon as they are loaded.
We had a similar Question asked earlier.
Script Tag - async & defer
And about the order of execution, JavaScript execution happens in the order they're placed in HTML. If your page relies on the JavaScript for certain events and if the JS Methods are loaded before your Page, then they'll result in the JS Error.
I would suggest you to use the CallBack functions where possible to avoid the above errors. Here is a good place to start to learn about the CallBack functions and how you can implement them.
Related
My question is related to async attribute in script tag.
In the https://javascript.info/script-async-defer link, I can see "The page content shows up immediately: async doesn’t block it."
But as far I understand, if we use the async attribute, fetching the script will happen in parallel but executing the script will block HTML parsing. So obviously page content will be blocked by the async attribute.
Can someone clarify what goes wrong in my understanding? will async block the page content?
The async attribute is used to indicate to the browser that the script file can be executed asynchronously. The HTML parser does not need to pause at the point it reaches the script tag to fetch and execute, the execution can happen whenever the script becomes ready after being fetched in parallel with the document parsing.
This attribute is only available for externally located script files. When an external script has this attribute, the file can be downloaded while the HTML document is still parsing. Once it has been downloaded, the parsing is paused for the script to be executed.
summary: async stops the parsing while script is being executed but after script execution as you can see in picture, still load parsing
I am trying to analyze some JavaScript code for which I make use of function rewriting so that calls to a JavaScript library go through my JavaScript code. My JavaScript code is part of a Chrome Extension. From a Chrome extension content script, I install/inject the code into the target page's DOM.
This works fine for functions that are induced after the load of page. The library calls go through my function. But, there's JavaScript code that runs while the page is actually loading (probably while the DOM is being rendered). This happens before my custom script is injected. This way, the function calls before the custom script is injected are lost to me, or those JavaScript calls do not go through my function.
I make use of Content Script to actually inject other JavaScript by appending to the DOM as mentioned in the following Stack Exchange question:
Insert code into the page context using a content script
I know I can cause the loading time of Content Script to be at the start/end of the DOM but this is another script file that I append to the DOM of the target page. I do not seem to understand how to control it.
The problem explained in Is it possible to run a script in context of a webpage, before any of the webpage's scripts run, using a chrome extension?
is exactly the same, but the solution does not seem to work. My intention is to make the injected script execute before any JavaScript code executes from the webpage. By specifying document_start in manifest.json, content script execution can be made to run before the webpage, but not the script that I inject through the content script (injecting script as explained in first link). This injected script is not running in any specific manner with respect to the webpage
Manifest.json:
Manifest file has the content script content.js added at document_start, so content.js is run before the target webpage (underlying page) runs.
"content_scripts":[
{
"matches":["<all_urls>"],
"js":["content.js"],
"run_at":"document_start",
"all_frames":false
}
],
content.js:
content.js has the below code with which I add the main.js to the DOM, so that I am actually able to interact with the JavaScript that is in the target page's environment. I do this from a different file and attach it to the DOM because I cannot interact with the target page's JavaScript through the Content Scripts, since they both do not interfere with each other.
To explain further, main.js has some JavaScript that intercepts JavaScript calls during the execution of JavaScript in target page. JavaScript in target page makes calls to a library and I intend just to write a wrapper on those library functions.
var u = document.createElement('script');
u.src = chrome.extension.getURL('main.js');
(document.head||document.documentElement).appendChild(u);
u.onload = function() {
u.parentNode.removeChild(u);
};
I expect that main.js is available in the target page's domain and any of the scripts in the target page, since I inject it through the content script that is run at document_start.
Assume I have a call to some JavaScript function like this in my target page HTML, someJSCall() is defined by the target page's domain.
<html onLoad="someJSCall( )">
In this scenario, main.js (code injected through my Chrome extension) is already available. So calls to the JavaScript library from someJSCall() function go through main.js wrapper functions.
This works fine.
The problem is when there are IIFE (immediately invoked function expressions) defined in the target page's JavaScript. If these IIFE calls make library calls, this does not go through my main.js interceptions. If I look at the files loaded in the browser through Chrome Dev Tools, I see that main.js is still not loaded while IIFE calls are executing.
I hope I have explained the problem in detail.
Based on the additional information you added to the question about 2.5 weeks after I answered, you are adding code to the page context by including a "main.js", which is a separate file in your extension, using a <script> that looks something like:
<script src="URL_to_file_in_extension/main.js"/>
However, when you do that you introduce an asynchronous delay between when the <script> is inserted into the page and when the "main.js" is fetched from the extension and executed in the page context. You will not be able to control how long this delay is and it may, or may not, result in your code running prior to any particular code in the page. It will probably run prior to code that has to be fetched from external URLs, but may not.
In order to guarantee that your code runs synchronously, you must insert it in a <script> tag as actual code, not using the src attribute to pull in another file. That means the code which you want to execute in the page must exist within the content script file you are loading into the page.
Needing to execute code in the page context is a fairly common requirement. I've needed to do so in browser extensions (e.g. Chrome, Firefox, Edge, etc.) and in userscripts. I've also wanted to be able to pass data to such code, so I wrote a function called executeInPage(), which will take a function defined in the current context, convert it to text, insert it into the page context and execute it while passing any arguments you have for it (of most types). If interested, you can find executeInPage() in my answer to Calling webpage JavaScript methods from browser extension and my answer to How to use cloneInto in a Firefox web extension?
The following is my original answer based on the original version of the question, which did not show when the content script was being executed, or explain that the code being added to the page was in a separate file, not in the actual content script.
You state in your question that you "can handle the loading time of Content Script to be at the start/end of the DOM", but you don't make clear why you are unable to resolve your issue by executing your content script at document_start.
You can have your script injected prior to the page you are injecting into being built by specifying document_start for the run_at property in your manifest.json content_scripts entry, or for the runAt option passed to chrome.tabs.executeScript(). If you do this, then your script will start running when document.head and document.body are both null. You can then control what gets added to the page.
For chrome.tabs.executeScript() exactly when your script runs depends on when you execute chrome.tabs.executeScript() in relation to the process of loading the page. Due to the asynchronous nature of the processing (your background script is usually running in a different process), it is difficult to get your script consistently injected when document.head and document.body are both null. The best I've accomplished is to have the script injected sometimes when that is the case, and sometimes after the page is populated, but prior to any other resources being fetched. This timing will work for most things, but if you really need to have your script run prior to the page existing, then you should use a manifest.json content_scripts entry.
With your content script running prior to the existence of the head and body, you can control what gets inserted first. Thus, you can insert your <script> prior to anything else on the page. This should make your script execute prior to any other script in the page context.
I have a Java Web Application, and I'm wondering if the javascript files are downloaded with the HTML-body, or if the html body is loaded first, then the browser request all the JavaScript files.
The reason for this question is that I want to know if importing files with jQuery.getScript() would result in poorer performance. I want to import all files using that JQuery function to avoid duplication of JavaScript-imports.
The body of the html document is retrieved first. After it's been downloaded, the browser checks what resources need to be retrieved and gets those.
You can actually see this happen if you open Chrome Dev Console, go to network tab (make sure caching is disabled and logs preserved) and just refresh a page.
That first green bar is the page loading and the second chunk are the scripts, a stylesheet, and some image resources
The HTML document is downloaded first, and only when the browser has finished downloading the HTML document can it find out which scripts to fetch
That said, heavy scripts that don't influence the appearance of the HTML body directly should be loaded at the end of the body and not in the head, so that they do not block the rendering unless necessary
I'm wondering if the javascript are downloaded with the html body during a request
If it's part of that body then yes. If it's in a separate resource then no.
For example, suppose your HTML file has this:
<script type="text/javascript">
$(function () {
// some code here
});
</script>
That code, being part of the HTML file, is included in the HTML resource. The web server doesn't differentiate between what kind of code is in the file, it just serves the response regardless of what's there.
On the other hand, if you have this:
<script type="text/javascript" src="someFile.js"></script>
In that case the code isn't in the same file. The HTML is just referencing a separate resource (someFile.js) which contains the code. In that case the browser would make a separate request for that resource. Resulting in two requests total.
The HTML document is downloaded first, or at least it starts to download first. While it is parsed, any script includes that the browser finds are downloaded. That means that some scripts may finish loading before the document is completely loaded.
While the document is being downloaded, the browser parses it and displays as much as it can. When the parsing comes to a script include, the parsing stops and the browser will suspend it until the script has been loaded and executed, then the parsing continues. That means that
If you put a call to getScript instead of a script include, the behaviour will change. The method makes an asynchronous request, so the browser will continue parsing the rest of the page while the script loads.
This has some important effects:
The parsing of the page will be completed earlier.
Scripts will no longer run in a specific order, they run in the order that the loading completes.
If one script is depending on another, you have to check yourself that the first script has actually loaded before using it in the other script.
You can use a combination of script includes and getScript calls to get the best effect. You can use regular scripts includes for scripts that other scripts depend on, and getScript for scripts that are not affected by the effects of that method.
I have a couple of questions about the attributes async & defer for the <script> tag which to my understanding only work in HTML5 browsers.
One of my sites has two external JavaScript files that currently sit just above the </body> tag; the first is jquery sourced from google and the second is a local external script.
With respects to site load speed
Is there any advantage in adding async to the two scripts I have at the bottom of the page?
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>?
Would this mean they download as the page loads?
I assume this would cause delays for HTML4 browsers, but would it speed up page load for HTML5 browsers?
Using <script defer src=...
Would loading the two scripts inside <head> with the attribute defer the same affect as having the scripts before </body>?
Once again I assume this would slow up HTML4 browsers.
Using <script async src=...
If I have two scripts with async enabled
Would they download at the same time?
Or one at a time with the rest of the page?
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?
This image explains normal script tag, async and 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 guarantees the order of execution in which they appear
in the page.
Ref this link : http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html
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.
HTML5: async, defer
In HTML5, you can tell browser when to run your JavaScript code. There are 3 possibilities:
<script src="myscript.js"></script>
<script async src="myscript.js"></script>
<script defer src="myscript.js"></script>
Without async or defer, browser will run your script immediately, before rendering the elements that's below your script tag.
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.
With defer, browser will run your script when the page finished parsing. (not necessary finishing downloading all image files. This is good.)
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.
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 following will happen.
<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>
Make parallel requests to fetch the files.
Continue parsing the document as if it was never interrupted.
Execute the individual scripts the moment the files are downloaded.
Defer
Defer is very similar to async with one major differerence. Here’s what happens when a browser encounters a script with the defer attribute.
<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
Make parallel requests to fetch the individual files.
Continue parsing the document as if it was never interrupted.
Finish parsing the document even if the script files have downloaded.
Execute each script in the order they were encountered in the document.
Reference :Difference between Async and Defer
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.
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 this 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.
Useful link when to use defer and async:
https://stackoverflow.com/a/68929270/7186739
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.
Rendering engine goes several steps till it paints anything on the screen.
it looks like this:
Converting HTML bytes to characters depending on encoding we set to the document;
Tokens are created according to characters. Tokens mean analyze characters and specify opening tangs and nested tags;
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;
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:
Execute macro tasks;
execute micro tasks;
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.
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.
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.
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.
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.
Both the async and defer attributes are used to load external JavaScript files asynchronously, which means that the HTML parsing and rendering process is not blocked while the external file is being downloaded and executed.
When you download a web page, 2 major things happen in your browser:
HTML Parsing
Loading of the scripts
2.1 Fetching scripts from the network
2.2 Executing the scripts line by line
However, there are some differences between the two attributes:
1.async attribute:
The async attribute allows the browser to download the script file asynchronously while continuing to parse the HTML document. Once the script file is downloaded, it will be executed immediately, regardless of whether or not the HTML document has finished parsing. This means that the script may execute before the rest of the page has loaded.
Example:
<script async src="script.js"></script>
2.defer attribute:
The defer attribute also downloads the script file asynchronously, but it will not be executed until the HTML document has finished parsing. This means that the script will be executed in the order in which it appears in the HTML document, and after the page has finished loading.
Example:
<script defer src="script.js"></script>
In general, the async attribute is used when the script file does not depend on other scripts or on the HTML document being fully loaded, while the defer attribute is used when the script file depends on other scripts or on the HTML document being fully loaded.
Summary:
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.
I have a section of a webpage that loads a JavaScript file from an external source and then kicks off an Ajax query.
When I load the page, I see the browser saying "waiting for example.com" a lot, so I think the dependency on this external JavaScript is slowing my initial page load.
Is there a way I can load this external JavaScript asynchronously so it doesn't slow the loading of the rest of my page at all?
It's good practice to put JS at the bottom, right above the closing body tag. In addition, use load events window.onload or $(document).ready() to fire your JavaScript after the page has loaded.
As far as loading JavaScript files themself asynchronously or on demand, you could inject it from another JavaScript function or event. But really you are doing the same thing as placing it at the bottom.
Check out the YSlow Guidelines for front-end optimizations.
You could use jQuery's .getScript() method, which is simply a wrapper for an AJAX call.
http://api.jquery.com/jquery.getscript/
This makes the request asynchronous, and gives you a callback that runs after the script has loaded.
You can see my answer here: Dynamic (2 levels) Javascript/CSS Loading
And grab the script from here (see the source). Use it at the bottom, and your scripts will not block other resources (and if you got more than one they will be downloaded in parallel cross-browser).
I wrote a library to asynchronously load javascript files with callbacks for when it loads:
https://github.com/ssoroka/sigma
Sigma.async_script_load('http://example.com/underscore/underscore-min.js', '_', function() {
_([1,2,3,2,3,1]).uniq();
});