This question often comes up in the context of optimizing the frontend of a product. Async and defer are attributes used on the script tag to include external JS files. Both allow the browser to NOT block HTML parsing while scripts are downloading, but they behave differently when it comes to execution. Let's look at how scripts are loaded without any extra attributes and with the async/defer attributes:
No attributes
Downloading external scripts blocks HTML parsing, and everything runs synchronously. If you include several scripts in <head>, the browser will wait until it has downloaded and executed each of them.
Async
With this approach, script downloading does not block HTML parsing and happens in parallel. The script is executed as soon as it has downloaded, even if HTML parsing is NOT finished yet.
Defer
Like async, defer does not block HTML parsing and downloads in parallel. However, deferred scripts always execute in the order they appear in the document, and only after the DOM has been fully built.