
Place CSS in the Head and JavaScript Files at the Bottom
Place CSS in the Head and JavaScript Files at the Bottom 관련
- CSS execution blocks rendering and prevents JS execution
- JS loading and execution block HTML parsing and prevent CSSOM construction
If these CSS and JS tags are placed in the HEAD tag, and they take a long time to load and parse, then the page will be blank. So you should place JS files at the bottom (not blocking DOM parsing but will block rendering) so that HTML parsing is completed before loading JS files. This presents the page content to the user as early as possible.
So then you might be wondering – why should CSS files still be placed in the head?
Because loading HTML first and then loading CSS will make users see an unstyled, "ugly" page at first glance. To avoid this situation, place CSS files in the head.
You can also place JS files in the head as long as the script tag has the defer attribute, which means asynchronous download and delayed execution.
Here's an example of optimal placement:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Optimized Resource Loading</title>
<!-- CSS in the head for faster rendering -->
<link rel="stylesheet" href="styles.css">
<!-- Critical JS that must load early can use defer -->
<script defer src="critical.js"></script>
</head>
<body>
<header>
<h1>My Website</h1>
<!-- Page content here -->
</header>
<main>
<p>Content that users need to see quickly...</p>
</main>
<footer>
<!-- Footer content -->
</footer>
<!-- Non-critical JavaScript at the bottom -->
<script src="app.js"></script>
<script src="analytics.js"></script>
</body>
</html>
Explanation of this approach:
- CSS in the
<head>
: Ensures the page is styled as soon as it renders, preventing the "flash of unstyled content" (FOUC). CSS is render-blocking, but that's actually what we want in this case. - Critical JS with
defer
: Thedefer
attribute tells the browser to:- Download the script in parallel while parsing HTML
- Only execute the script after HTML parsing is complete but before the
DOMContentLoaded
event - Maintain the order of execution if there are multiple deferred scripts
- Non-critical JS before closing
</body>
: Scripts without special attributes will:- Block HTML parsing while they download and execute
- By placing them at the bottom, we ensure that all the important content is parsed and displayed first
- This improves perceived performance even if the total load time is the same
You can also use async
for scripts that don't depend on DOM or other scripts:
<script async src="independent.js"></script>
The async
attribute will download the script in parallel and execute it as soon as it's available, which may interrupt HTML parsing. Use this only for scripts that don't modify the DOM or depend on other scripts.
Reference: