To answer your immediate question, the Script Element documentation on MDN will help.
Defer:
Scripts with the defer attribute will prevent the DOMContentLoaded
event from firing until the script has loaded and finished evaluating.
Async:
This is a Boolean attribute indicating that the browser should, if
possible, load the script asynchronously.
An async script will not hold up the DOMContentLoaded event from firing.
There are several better ways of causing dom content to appear after a delay that will not block the UI thread like you are doing; this is a very bad practice.
An extract from DOMContentLoaded:
Synchronous JavaScript pauses parsing of the DOM. If you want the DOM
to get parsed as fast as possible after the user has requested the
page, you can make your JavaScript asynchronous
The normal practice would be to append dom content after the document is loaded. You could still do this with a timeout but usually the additional dom content would be loaded after some other asynchronous action like a response received from fetch.
Here is an example of appending dom content after a delay:
function wait(ms){
window.setTimeout(function() {
var element = document.createElement("h1")
element.innerText = "Hello World!"
document.body.appendChild(element)
}, ms)
}
wait(5000);
<html>
<head>
<script src="home.js"></script>
</head>
<body>
</body>
</html>