I'm surprised how many web working people aren't aware of all the differences between synchronous versus asynchronous javascript. To alleviate some of the confusion, I'd like to discuss some of the differences.

Say I have a script with the source of http://sample.com/my-script.js. This can be loaded either synchronously (sync from here out) or asynchronously (async from here out).


Synchronous Scripts

When you load a script as sync, you do a couple things:

  1. Load the script so it has to finish loading before the rest of the page loads.
  2. Directly write the tag to the page.

This method is usually achieved from manually adding a script to your page source like so:

	<script type="text/javascript" src="http://sample.com/my-script.js"></script>

Sync writes can also come from a script using a "document.write" function call. For example, I could add another sync script from within my currently running sync script with:

document.write("<script src='script2.js'></script>");

Now, can we think of any problems with this?


Before I discuss issues, I want to describe how a sync script or element will run on the page.

  1. A user enters a page.
  2. The page starts loading from the top down in the code.
  3. Sync scripts are typically found in the <head> of the page. When the loading hits the sync script, the page load pauses, the script runs.
  4. The script finished, the page load continues.

Given this order of events, the first issue that pops out to me is: what if something in my script (step 3) errors or stalls? With sync javascript, if this happens, it has the potential to break your whole web page. Obviously, this can be a big problem, so a lot of sites will only do sync scripts that they've created and house on their own server. Any third-party scripts (advertisingwill be implemented via other methods.

Another issue with sync scripts is timing. This wasn't too bad in the past, but the more that our web society is moving to tracking users and mobile development, making the pages fast is a big concern. Sync scripts usually don't affect this too much, but if you did have something in the script that was slow, this would directly affect your page load and make it slow.


Asynchronous Scripts

Obviously, the two items above for sync calls can be of big concern, so we have an alternative option to load scripts. Async javascript allows us a way to have safer scripts that don't affect the page as much. Here's how they work:

  1. A user enters a page.
  2. The page starts loading from the top down in the code.
  3. The async script is hit and starts to load, the page load continues. (Both run in parallel).
  4. The page load and async script finish loading on their own, independent of each other.

Async scripts can be added in a few different ways (manually, via a library, hard-coded, through another script, etc). A very common example is running an anonymous function. Something like so:

		var s = document.createElement('script');
		s.type = "text/javascript";
		s.src = "//sample.com/my-script.js";

You can already see how much safer this can be. Since async scripts are loaded independent of the page, they are ideal for timing since they don't affect the page load process. They are also safer since a failing async script won't affect the rest of the page.

This method is becoming a large standard across the internet, especially when it comes to the middle layer of analytics, marketing, and other tracking. Ideally, you'd want this functionality to load without affecting your page because it isn't the highest priority. Because of async scripts, amazing things can be built as well. Examples you constantly will see is any type of dynamic content - one page apps, popups, dynamic saving, and more.

This sounds great! Any downsides? The biggest downside to these scripts happen when certain timing or content modification happens. Because async runs in parallel with your page, you can't have main page load parts that are reliant on the script built in to the script because you have no way to predict exactly when a piece of a script will run.


Which should I use?

Depends on the situation obviously. A good question to ask: Does the page rely on this script to run? If the answer is yes, there's a good chance that it needs to be synchronous. Here's some use cases that almost always fit that description:

  1. Libraries (jQuery, bootstrap, angular, etc.).
  2. Content Scripts (add content, modify content, remove content) that should happen to determine the structure of the page.
  3. Externet Scripts that must be loaded to manage a look or functionality of a page. These might be adding ads, click handlers, etc.

Outside of these, you'll almost always want to use async calls. Some examples:

  1. Dynamic content.
  2. Saving without reloading.
  3. Various event handling.
  4. Third-party tagging.
  5. Single page apps.
  6. much more...


Other Comments

Hopefully this has helped clarify the differences between these two methods of loading scripts! I'd like to note a couple things that happen occasionally, but aren't always easy to debug.

  1. In the example async script above, when you look at the page after it has been loaded, it will appear that the "my-script.js" was loaded as a synchronous script at the end of the <head>. This isn't the case, but it can be misleading. There is nothing to worry about in this case, but it is something to be aware of, especially when observing code from third-party vendors.
  2. If you are getting warnings in your console about document.write or sync/async errors, there's a good chance you are trying to load a sync script via async methods either manually or through another script. Another error you might get is the script not working as you might expect. This may or may not show errors, so these can be very difficult to find. However, once you find these, the easy way is to change the sync script to load properly. This will mean either including it in the source code, or converting it to by an async script.


If you've found any other useful info related to sync and async script loading, feel free to post in the comments!