How to wait until a page has loaded in JavaScript

Reading Time: 2 minutes 🕑

Last updated: September 14, 2022.

It is often useful to wait until a page has loaded to run some of your JavaScript code.

For example, you don’t want to try to manipulate DOM elements before they have been read and loaded.

And you don’t want to display a ‘loading complete’ message before the page has fully loaded, including any external resources like images or video.

In this tutorial, we cover how to wait for these two different type of page loads.

Table of contents

Wait for all DOM elements to exist

If you want to make sure that all HTML elements in your markup have been read and are fully loaded by the time you run your code, you want to wait for the DOMContentLoaded event.

This event occurs on the global window object. So to listen out for it, you add an event listener to window that fires its associated function when the DOMContentLoaded event occurs:

window.addEventListener('DOMContentLoaded', () => {
    const div = document.getElementById('my-div');
    div.textContent = "DOM content has loaded!";
})

This means that you can add a script before the closing </body> tag in your script and it will have full access to all DOM elements.

For example, the following code would throw an error because div has not been read or loaded by the DOM parser when the script is executed:

<script>

    const div = document.querySelector('div');
    div.textContent = "DOM content has loaded!"; // Uncaught TypeError: Cannot set properties of null (setting 'textContent')

</script>

<div></div>

But wrap that code in an event listener function that waits for the DOMContentLoaded event and it will write the content to div:

<script>

    window.addEventListener('DOMContentLoaded', () => {
        const div = document.querySelector('div');
        div.textContent = "DOM content has loaded!";
    });

</script>

<div></div> <!╌ "DOM content has loaded!" written inside div ╌>

Wait for the page to load completely

If you want to wait for the page to load entirely, including all external resources such as images and stylesheets, you need to wait for the load event:

<script>

    window.addEventListener('DOMContentLoaded', () => {
        const div = document.getElementById('my-div');
        div.textContent = "All resources loaded!";
    });

</script>

<div></div> <!╌ "All resources loaded!" written inside div ╌>

Prevent unnessary waiting

It is a common mistake to listen out for the load event when a script could run already at DOMContentLoaded.

Ensure you do not wait unnecessarily long to optimize page load speed!

SEO considerations

Although it may be tempting to place all of your scripts in the <head> section of your HTML, this can sometimes be bad practice for SEO (Search Engine Optimization).

This is because the script is downloaded as soon as it is encountered, meaning that a bulky script placed before the main content in your HTML can slow down initial page loading speed.

It is therefore still advisable to place all scripts that are non-critical to initial page load before the closing </body> tag in your script.