CommonLounge Archive

JavaScript: Callbacks and Pre-loading assets

September 26, 2018

In this tutorial you’ll learn about a special type of functions — callbacks.

We will also look at pre-loading static assets like scripts, images and stylesheets into the browsers cache so that they can be instantly fetched from the cache which is a lot faster than downloading from a remote URL.

Let’s get started!

Set-up for this tutorial

For this tutorial, to ensure that everyone sees similar results and is able to run the code properly, we will change some settings in Google Chrome.


Open up the console using Ctrl + Shift + J. In the top bar there is a tab called Network. Click on it. You should see:

Network tab in Developer tools


Check the box next to Disable cache by clicking on it.

Disable cache

In this tutorial, we will be talking about preloading images in the background. However, by default, the browser caches the image, and then reuses the image from the cache instead of downloading it. Disabling cache allows you to simulate the experience for someone who visits the site for the first time.


Then, click on the dropdown with label Online (on the extreme right), and select Fast 3G.

Fast 3G Network throttling

This sets the download and upload speed for this browser tab. Otherwise, if your internet is too fast, it will be difficult to notice the effect of preloading images in the background.


These settings will be required for both the following sections so keep them on until the end of this tutorial. Refresh your page once to make sure the settings are applied.

If you switch to a different tab, or close the Console and refresh, then your settings will be reset. Make sure you keep the Console open (then it is okay to refresh).

You can monitor when Chrome starts downloading an image and when it completes downloading the image by keeping the Console open, and staying on the Network tab. You’ll see new rows of information appear when new network requests are made. Chrome will also tell you how much data was downloaded, and whether or not the cache was used.

Callbacks

Callbacks aren’t really a feature of JavaScript like Object or Array, but instead just a certain way to use functions. A callback function is a function that is passed as a parameter to another JavaScript function, and the callback function is called back (hence the name callback), inside of the function it was passed to.

Callbacks can be both synchronous and asynchronous. If the execution takes place in the same order as the code is written, then it is said to be synchronous, otherwise asynchronous.

Synchronous callback function

Let’s take a look at an example:

function greet(name) {
    alert("Welcome, " + name);
}
function greetPerson(callbackFunction) {
    var name = prompt("Enter your name");
    callbackFunction(name);
}

We can call the second function like

greetPerson(greet);

This will take the name of the user, and then pass it to the callbackFunction which is greet in this case. This runs in sequence, therefore it is a synchronous callback function.

Asynchronous callback function

To understand asynchronous callbacks and why they are useful you first have to learn about asynchronous (often shortened to async) programming. Let’s look at an example:

<html>
    <body>
        <button onclick="addImage()">Download image</button>
        <br><br>
        <script>
            function addImage() {
                var img = new Image();
                img.style.width = "400px";
                img.src = "https://imgur.com/download/paxYhVi";
                document.body.appendChild(img);
                var confirm = document.createElement('p')
                confirm.innerText = "Image downloaded";
                document.body.appendChild(confirm);
            }
        </script>
    </body>
</html>

The function addImage() should downloads an image from a URL and then adds it to the body using appendChild().

First, we create a new image element, set its width to 400px and its src attribute to a URL, and add it to the document.

Then, we add a paragraph with text ”Image Downloaded” to the document.


The image is moderately large in size (approximately 210 KBs) so it takes reasonable amount of time to load. When you click on the button you should see the image loading slowly:

Downloading image

There are two problems with the above code that we would like to fix.

  1. Even though we added the image first and then the text, you see the text "Image downloaded" appear immediately (even before the image has finished downloading).
  2. The image appears a little at a time. We want the image to appear all at once.

These problems happen JavaScript did not wait for the download to finish (after img.src = "https://imgur.com/download/paxYhVi";) and continued execution of code (adding image and text to the document). Meanwhile the download is still happening in the background.


We can solve these problems using a callback!

We want the image and text to be added to the document once the image has loaded. To do this, we need to:

  • Create a new callback function.
  • Call this function when the download is finished

Here’s the revised code:

function addImage() {
    var img = new Image();
    img.style.width = "400px";
    img.src = "https://imgur.com/download/paxYhVi";
    img.onload = function() {
        document.body.appendChild(img);
        var confirm = document.createElement('p')
        confirm.innerText = "Image downloaded";
        document.body.appendChild(confirm);
    }
}

All elements have an onload event which gets triggered when the element has finished loading. We assign the callback function to the img.onload property.

Refresh the page and you should see the image appear all at once (takes some time to load, but appears all at once).


That’s better, but there’s still room for improvement.

Preloading

The downloading of the image starts only after the button is clicked. We can utilise the time between when the page has loaded and when the user clicks the button to download the image in background. That way, when the user clicks on download image, the image will appear immediately.

In this tutorial we will only look at how to preload images but you can also load other assets like stylesheets or scripts using the same logic.


Okay, let’s write the code:

<html>
    <body>
        <button onclick="addImage()">Show image</button>
        <br>
        <script>
            var img = new Image();
            function preloadImage() {
                img.src = "https://imgur.com/download/paxYhVi";
                img.onload = function() {
                    var confirm = document.createElement('p')
                    confirm.innerText = "Image downloaded";
                    document.body.appendChild(confirm);
                }
            }
            function addImage() {
                img.style.width = "400px";
                document.body.appendChild(img);
            }
            window.onload = preloadImage;
        </script>
    </body>
</html>

We have split our earlier function addImage() into two. Now, half the work is done by preloadImage(). In particular, preloadImage() downloads the image and confirms once the download is complete.

window.onload is the method which gets executed as soon as the HTML document finishes loading. We’ve assigned the window.onload to preloadImage() so that it starts loading the image as soon as the page is opened.


Now, open the window. In about 2 seconds, you’ll see the text “Image Downloaded” appear. Then, click on the Show Image button, and you’ll see the image appear instantly.

We have let the img.onload function be there so that it is easy for you to see when the image finishes downloading. If you click Show Image before the image has finished downloading in the background, you will see it loading.


That’s about it for preloading images. You can try preloading other assets as an exercise. For example, to load an external script you can create a <script> tag element using document.createElement("script") and then assign the src of this newly created element to the source of the script.

Summary

In this tutorial, you learnt

  • How to disable browser cache, throttle network speeds and monitor the network requests. This is helpful for testing your web app.
  • What are callback functions and how they can be useful.
  • How to preload assets in the background.

Kudos!


© 2016-2022. All rights reserved.