Lesson Description
The "Loading JavaScript in the Browser" Lesson is part of the full, Getting Started with JavaScript, v3 course featured in this preview video. Here's what you'd learn in this lesson:
Kyle explains how JavaScript is loaded in a browser. Initially, the browser downloads the HTML file, then parses it to build the Document Object Model (DOM) representing the site's structure. When encountering a script tag, the browser pauses HTML parsing to download and execute the JavaScript, impacting website loading speed. Kyle discusses methods like async and defer attributes to optimize JavaScript loading, highlighting defer as a preferred choice for predictable execution order and efficient parallel downloading without interrupting HTML parsing.
Transcript from the "Loading JavaScript in the Browser" Lesson
[00:00:00]
>> WebDevSimplified: Now the final thing we need to talk about before running our different JavaScript is how our JavaScript is loaded specifically in the browser because it's a little bit complicated. The way that the browser works when parsing HTML is at first to download your HTML file. So what happens is when I try to go to this website, localhost 5500, it's going to go to that index HTML file. It's going to download this entire file directly from the page, and then it's going to start parsing that file from beginning to end.
[00:00:26]
So it reads it line by line. It reads the first line and then the second line, and the third line and the fourth line. And while it's reading through that, it's building up something called the Document Object Model. This is also referred to as the DOM, and essentially you can think about that as the entire structure of your site. Where do all your buttons live? Where is your images at? Where are your paragraphs at?
[00:00:44]
Where are your headers, your footers? Every single thing on your page is represented inside this Document Object Model or the DOM. So it's essentially trying to figure out where to put everything on your page by parsing through and reading it line by line. Once it finishes reading out your entire HTML all the way to the bottom line by line and it built out that whole Document Object Model, it then takes that code and renders it out directly to your page so that you can view it as a user.
[00:01:09]
So it's like this four-step process. Download the file, read the file, build out what the page should look like, and finally show the page to the user. That's how it works in the most basic sense when you don't really have anything else going on. Once you start adding JavaScript into the mix though, it gets a little bit more confusing. As soon as this HTML parser gets to a script tag, which we talked about how you create that script tag and pass it in whatever your script name is, as soon as it gets to that, instead of continuing on and reading the next line and the next line and the next line, it instead immediately pauses and downloads the JavaScript.
[00:01:41]
So in our particular example, it'll read through and parse our code perfectly fine until it gets up to this point right here where it says script source script.js. It'll get to this point and it'll say, oh, I need to get this JavaScript file, and it immediately stops. It then goes off, downloads that brand new JavaScript file, and importantly, it executes all the code in that JavaScript file. So in our case, it'll run this particular piece of code after it downloads it.
[00:02:06]
And finally, once it downloads it and then runs the code, it continues on and starts going, OK, let's parse the next line and the next line and the next line, and so on. So when you get to a JavaScript file, it'll load that file and then parse that and execute that file before continuing on. This is generally not the best behavior for a user though, because it slows down your website. For example, I now need to wait to download the HTML, then I need to wait to download all the JavaScript.
[00:02:29]
Then I need to wait for all the JavaScript to execute, and then finally I can finish rendering the rest of the HTML to the user. It's a very slow process, but this is the default behavior for JavaScript. This is why they also created two additional ways that you can render out your JavaScript instead of making it do this loading tactic. The first one is kind of an offshoot, so this is kind of like a 1.5 method, and this is by putting your JavaScript in the body instead of in the head.
[00:02:54]
You may see this in older code, where a script tag instead of being put up here inside of the head, is actually moved all the way down at the very bottom of the body, and this allows it to actually parse what all of your HTML should look like before running the code inside of your JavaScript. Nowadays this isn't really something that you need to do though, because there's alternative methods you can use instead.
[00:03:14]
I just want you to know if you see this inside of code, it's purely to get around that loading problem that we just talked about. Now we're going to move ours back up into the head and let's go ahead and look at some of these alternative methods. The first one is going to be the async tag. So inside your script tag you can add a brand new tag called async, and what this async tag does is essentially allows you to download your JavaScript in parallel with the rest of your HTML.
[00:03:37]
So if we look at this chart here, it parses the HTML and as soon as it gets to a point where it tries to reach a JavaScript file, so in our case, when it gets to the line for this JavaScript file, instead of stopping right there, it just continues on going. It says, OK, let's look at the head, let's look at this line, let's look at this line. Continues going, but in the background it's going to download that JavaScript file for you to use.
[00:03:57]
So now we're saving the user some time because instead of waiting for that file to download, it just downloads it in the background so we can do two things at once. Then once that file finishes downloading, we then move on to the execute step where it actually runs the code in there. So in our case, let's say it downloads this file, it runs this line, it runs this line, it runs this line, and then finally the file gets downloaded.
[00:04:18]
Immediately once the file gets downloaded, it jumps into that file, runs all the code in that file, and then continues from wherever it was. So if it stopped here, it then continues on and starts parsing the rest of your HTML. This is great because we offloaded that section of downloading to make it happen in parallel, but again, we're still interrupting the parser partway through because we get this file and we start executing the code inside of it.
[00:04:40]
So this solves one of the problems, but isn't the ideal solution. This is where the final attribute, which is the defer attribute, comes in. This works just like async where if we get to a JavaScript file, it'll get that file and download it in the background, so we don't have that additional waiting. But then instead of executing the file immediately when it downloads, it instead waits until it parses all the JavaScript or all the HTML on your page.
[00:05:04]
So we get our script file here. If this had that defer attribute on it, what's going to happen is it gets that script file. It'll keep running through every line while it's downloading in the background. As soon as it finishes downloading that file, it just keeps going on your HTML, doesn't run it yet, finishes out all the rest of your HTML rendering, and then finally, once it gets to the very bottom of your HTML parsing, then we run the code inside of here.
[00:05:31]
Yes, question? Is this the same as taking the script and putting it below in the body? Yeah, in the bottom. Yeah, so it's going to be similar but slightly different. So by putting your script tag at the very bottom of your body, essentially we take this graph right here and we move the section for downloading and executing our JavaScript to the very end of the HTML parsing. But we still don't save any time because we still have to download the JavaScript separately from the HTML parsing, so we don't have that ability to do it in parallel.
[00:06:01]
The only benefit to rendering it at the very bottom is that all of your HTML parsing will happen before the JavaScript executes. Which is important because if you have code inside of your JavaScript file that references the document and references maybe a button on your page, you need to make sure that the browser knows there's a button on that page and it only knows that once it renders through all of your different HTML.
[00:06:25]
So by putting the script tag at the very bottom of your document, just like this, we make sure that all of the code inside of our body is rendered before it actually gets to that page. The benefit of using the defer attribute instead is that we still get the benefit of having that code at the very bottom. It runs after all of our HTML parses, but we also get the benefit of letting it download in parallel in the background.
[00:06:46]
So it'll download your code quicker for the user and it'll still execute at the very end after everything loads onto your page. It kind of gives you the best of both worlds where you get that quick download and the ability to execute the code at the right point inside the workflow. So defer is the keyword that I use whenever I load my JavaScript. I always put it in the head and I always use the defer attribute to load it just because I get that benefit of the parallel download and I get the ability to make sure it always runs at the end of my file.
[00:07:12]
Another important thing about the defer keyword is that it makes sure that it runs your code in a predictable order. What that means is let's say that I had multiple script files here. So I had script.js and I had script2.js. So two different files they're going to be running inside my application. With the defer attribute, it doesn't matter how long each one takes to load, it'll always run this script file first, and it'll always run this script file second.
[00:07:35]
So always make sure it runs them in the correct order. That's a really nice thing about the defer keyword. If I leave the defer keyword off, it also does the same thing. But using the async keyword for both of these means that they can execute in any order, whichever one downloads first will execute first. So if script 2 is a small file and the normal script up here is a large file, script 2 may run first because it's a smaller file, so it's more difficult to know the correct order things run in.
[00:08:01]
This is another reason why I prefer the defer keyword for those particular things. In our case, we don't have that file, so let's completely remove that. And we'll move on and we kind of get a chart here comparing the different ways and this really emphasizes that speed aspect we get. You can see in the normal way this chart is much wider, it's much longer because we have to download this JavaScript in sequence, while with this async and defer way we can download this in parallel, which saves us a bunch of time.
[00:08:26]
The other big benefit of defer, as we talked about, is it allows you to execute your JavaScript after the HTML is parsed, which is really important for making sure all the different buttons and everything are loaded on your page. Yes. Would async and defer conflict with each other if you had both tags on or yeah, they wouldn't conflict with each other. They would essentially both work their own way.
[00:08:49]
So async, if you had an async and defer attribute, I'll just kind of show an example here. Let's say this one was async. There we go. And the one below it, script 2 is what we'll call it, is defer. The async one will still download immediately when it gets to it. The defer one will also download, so they're both downloading in the background. The difference is the async one, once it finishes downloading, executes immediately.
[00:09:09]
So if it finishes downloading before your HTML is parsed, it'll execute then. If it finishes after your HTML is parsed, it'll execute then. It doesn't care when it executes. Defer will always wait till the end. So even if you have both of them mixed together, defer will always wait until the end, and then async will just execute as soon as it's downloaded.
Learn Straight from the Experts Who Shape the Modern Web
- 250+In-depth Courses
- Industry Leading Experts
- 24Learning Paths
- Live Interactive Workshops