For more tips like this, sign up to the weekly newsletter!

Use script defer to wait for the DOM

<script>s are run when the browser sees them during DOM parsing. This means that elements on the page that follows a <script> aren't accessible:

<script>
  document.querySelector("#test"); // null
</script>
<div id="test"/>

This is usually countered by either putting the <script>s to the bottom of the HTML body, or waiting for the DOMContentLoaded event:

<script>
  document.addEventListener("DOMContentLoaded", () => {
    document.querySelector("#test"); // HTMLDivElement
  });
</script>
The defer attribute

The same can be achieved by using the defer attribute of <script>:

<script defer src="script.js"></script>

defer instructs the browser to load the script, but execute it only after the page is loaded. This way, you don't need to add an event listener, as the DOM will be ready by the time the script runs.

As an added benefit, the order of execution is unchanged, so if a <script> is before another one, they will be run in this sequence.

One thing to keep in mind though: it only works for external scripts, i.e., with an src attribute pointing to a js file. For inline scripts, the defer attribute is ignored.

Try it
References
Learn more: