01.11.2020 site-news webdesign techarticle

Keeping the Javascript in check (continued)

With the advent of HTML5, Javascript became an even more important part of every website than it ever was. Canvas, WebAudio, WebRTC, just to name a few, became very important to functionality. Without, web games would still be stuck with the dread awfulness of Flash. Some Games as we know today, wouldn’t be possible.

When a browser reads a webpage it may encounter your javascript. You are probably used to doing it this way:

<html>
<head>
    <script src="my_script.js">
    <title>Example</title>
</head>
<body>
    <div>Some content</div>
</body>
</html>

While this works just fine, it will make the browser stop, read and interpret the code, then continue. This is bad. You want a snappy, fast web page, where the user can start using it asap after getting the base page.

So, how do we solve this? First of all, we move all the Javascript to the bottom of the page. It will not hurt functionality.

So, our second version looks like this:

<html>
<head>    
    <title>Example</title>
</head>
<body> 
    <div>Some content</div>
    <script src="my_script.js">
</body>
</html>

This is already good. The browser can now read the whole page and stops at the bottom to read your scripts. While some parts of the page may already be displaying, the user still cannot fully use the page as the loading circle is probably still running. So, we need to tell the browser to read to the end, before it cares about the Javascript.

The keyword for this functionality is defer. Here is how to use it:

<html>
<head>    
    <title>Example</title>
</head>
<body> 
    <div>Some content</div>
    <script defer src="my_script.js">
</body>
</html>

If defer is present, Javascript will execute the script after page has loaded. You can also use async, which makes the javascript execute while the page is loading, but if you are using Javascript sparingly like me, you can get away with defer just fine.

However, if you execute your code arbitrarily in the page, you may run into the issue, that the browser tells you that some functions do not exist anymore.

We can counteract this by adding an event listener:

// Plain JS
document.addEventListener('DOMContentLoaded', () => {
    // Initialization code goes here
});

// JQuery
$( document ).ready(function() {
    // Initialization code goes here
});

Any initializer, general code that is supposed to run when the page loads goes in there. This ensures that the code will not be executed before the Javascript evaluation has been completed. Your scripts will work as before. This is minimal effort to get the best performance out of your site, without actually having to rewrite any code.

While testing this, you may not notice any difference with your ultra fast web connection or local testing. I have 250 Mbit/s myself. Use the developer tools in Chrome or Firefox once in a while to throttle your connection to mobile speeds such as e.g. “Slow 3G” in the Chrome Dev Tools. Some countries do not have better speeds. You WILL notice the difference with long pages. Think about those less fortunate.

Here is a demonstration of the page load with the defer keyword using the “Slow 3G” preset in Chrome:

Look at the document, named 2/ here, as stated in Type. See how it is loaded first with the rest is coming in after? This is the exact effect we want to have. Scripts, fonts, stylesheets all load in later.

On the next part, we are going to talk about how to do the same with images and external resources. Stay tuned.

Link to the author's twitter Link to the authors ko-fi page