Technically it's only best practice if you don't care "much" for the sequential loading of script files. You figured out you need a library first before you can call it. Hence people load all of their custom scripts in the bottom, after the HTML is loaded, so they don't need to take care of that particular
DOM loaded event and to counter render blocking scripts which is what happens when you simply put them all in the head tag.
With that info in mind, I say best practice is one bundled script file put on
async mode loaded from the head-tag, preferably minified. Achievable with a grunt/gulp setup or some sort.
<head> <title></title> <script src='path-to-bundled-script.js' async='async' /> </head>
async attribute makes sure the page loading doesn't wait on this script to be fully loaded. It still does wait on more than one http requests, hence the bundeling for sequential execution.
So when you are developping and you don't have your grunt/gulp setup completed for this bundle, you will hit errors, saying that libraries aren't loaded or symbols aren't recognized.
To solve this you can use the attribute
<head> <title></title> <script src='path-to-library.js' defer='defer' /> <script src='path-to-library2.js' defer='defer' /> <script src='path-to-library3.js' defer='defer' /> <script src='path-to-custom1.js' defer='defer' /> <script src='path-to-custom2.js' defer='defer' /> </head>
With the defer attribute, the page load will wait for the scripts to be executed, but not for the HTML to be completely loaded.
Using this technique, you can forget about the closing body tag as best practice and you'll gain speeds testable with google's pagespeed insight
Feel free to see a live example here