HTML Structure

Back To TOC
Reconfigure Loading For Page Speed

Restructure page resources with a progressive approach to load the most critical CSS & JavaScript as soon as possible while less critical resources load in the background without render blocking.

Jump To The Result

The file resources of a website work together to form the content, visual styling and functionality users see and interact with in the browser. HTML code is the foundation of each page and coordinates how those resources are loaded. Optimizing the structure of HTML is an important step to streamline the loading process and ensure that pages load quickly and efficiently.

Render Blocking

When a user navigates to a page, the web browser loads and examines the HTML code. Any CSS or JavaScript files encountered in the HTML are downloaded and applied to the page.

This sequence is known as the critical rendering path and is particularly important for above-the-fold content. CSS and JavaScript references are considered render blocking because the page may appear blank or incomplete to the user until those files are downloaded and interpreted by the browser.

For a very simple page with only a few small files transferred over a fast internet connection, the loading process is nearly instantaneous. However as the HTML becomes more complex and CSS and JavaScript files become larger, more numerous or loaded over slower internet speeds, the display of the page can become noticeably delayed.

Consider the basic structure of an HTML file:

HTML
<!doctype html>
<html lang="...">
<head>
    <meta charset="utf-8">
    <title>Page Title</title>

    <!-- conventional render blocking file references -->
    <link rel="stylesheet" href="styles.css">
    <script src="scripts.js"></script>

</head>
<body>
    <!-- visible content goes here -->
</body>
</html>

In general, the <body> section contains the visible content of the page, like text and images, and the <head> section organizes the code and file references that aren't directly displayed to the user. Given the render blocking effect of conventional CSS and JavaScript references, any files placed in the <head> this way have to be downloaded, applied or executed before the user can see any content.

A Progressive Approach

A more efficient strategy is to separate and prioritize the most critical resources to load as soon as possible. Resources that are not essential to the initially-visible part of the page can then be loaded asynchronously without render blocking or deferred to the end of the loading process. The exact CSS and JavaScript considered critical will depend on the content, layout and functionality of each page, but will likely focus on above-the-fold content elements.

CSS

For CSS, a priority-oriented approach means applying critical styling immediately, while loading non-critical CSS in the background without delaying the initial display of the page content.

Critical CSS

Critical styles are those that apply to the initially-visible or above-the-fold elements of the page. This can be done with a small, conventionally-loaded (and purposefully render blocking) external CSS file:

HTML
<!-- other <head> stuff -->

<link rel="stylesheet" href="critical.min.css"> <!-- under ~10KB -->

</head>

In this case the render blocking effect is desirable to avoid unstyled content from appearing before the CSS is applied - sometimes called a flash of unstyled content - which can be disorienting to users. This single render blocking file should be kept as small as possible, ideally under ~10KB minified and compressed.

Inline Critical CSS

A single small render blocking CSS file is a good strategy for critical CSS and doesn't impact page speed on an otherwise well-optimized page. But what if you want to eliminate all render blocking CSS resources?

To eliminate all render blocking CSS, critical styles can be added to the page as an inline style block. This technique avoids the render blocking effect of a separate file reference by embedding the critical CSS directly in the HTML.

HTML
<!-- other <head> stuff -->

<style>
    .main-menu {...}
        .main-menu a {...}
    /*-- etc --*/
</style>

</head>

A potential downside to this method is that inline CSS won't be cached by the browser and is therefore re-loaded each time the page is viewed. HTTP/2 may also make this method less advantageous.

Non-Critical CSS

Non-critical CSS resources for content that isn't initially visible should be loaded in the background without blocking further rendering of the page. This is often called asynchronous CSS loading.

Asynchronous CSS

For the best results, explore asynchronous CSS loading in detail to ensure that non-critical CSS resources don't hinder loading speed:

Asynchronous CSS

The recommended method for most cases uses a combination of the media attribute and a bit of inline JavaScript:

HTML
<!-- other <head> stuff -->

<!-- optionally increase loading priority -->
<link rel="preload" href="non-critical.css" as="style">

<link rel="stylesheet" href="non-critical.css" media="print" onload="this.onload=null;this.removeAttribute('media');">

<!-- no-JS fallback -->
<noscript>
    <link rel="stylesheet" href="non-critical.css">
</noscript>

</head>

This technique loads the non-critical CSS in the background and with a low priority, although as shown, an optional preload resource hint can be added to increase loading priority. Since it relies on JavaScript, a conventional <link> reference is an easy fallback.

Media Conditions

Media queries are another great way to manage render-blocking CSS by selectively prioritizing critical resources based on conditions like screen size. All files will be downloaded, but with appropriate priority, and only CSS with matching media conditions will block rendering.

HTML
<link rel="stylesheet" href="critical-general.css">
<link rel="stylesheet" href="critical-large.css" media="(min-width:60em)">

JavaScript

Much of the same strategies apply to optimizing JavaScript resources, however JavaScript typically acts on the HTML once the page is loaded so in most cases all JavaScript can and should be loaded without render blocking.

Unlike CSS, JavaScript references can use the purpose-made async and defer attributes to instruct those files to download in the background at a low priority without interrupting the rendering process. Although their loading behavior is the same, async and defer follow different rules for when the JavaScript runs.

async

defer

In most cases, the best strategy is to defer all JavaScript, so a fully-optimized setup will look like this:

HTML
<!-- other <head> stuff -->

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

</head>

Inline JavaScript

Ideally all inline JavaScript should be moved to a separate file to maximize caching, but if inline <script> blocks can't be avoided and they also rely on a defer'd external file, the inline JavaScript can be wrapped with a DOMContentLoaded event listener to run after the defer'd file:

HTML
<!-- other <head> stuff -->

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

</head>
<body>
    <!-- page content -->

<script>
    document.addEventListener('DOMContentLoaded', function(){
        // more jQuery-dependent stuff
    });
</script>

</body>

Javascript contained in a defer'd file that depends on another defer'd file can use this same kind of event listener. For example, if along with some vanilla JavaScript that should load and run first, the scripts.js file above also contains some jQuery code that relies on jquery.js, that jQuery code can be wrapped with a that same kind of DOMContentLoaded event listener to ensure that it runs after jQuery.

All Together

Putting it all together, this is a simple example of HTML structured to separate and prioritize critical versus non-critical CSS and JavaScript resources, minimizing delay for above-the-fold content:

HTML
<!doctype html>
<html lang="...">
<head>
<meta charset="utf-8">
<title>Page Title</title>

<link rel="stylesheet" href="critical.css"> <!-- can be optionally inlined -->
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.onload=null;this.removeAttribute('media');">

<!-- no-JS fallback for non-critical CSS -->
<noscript>
    <link rel="stylesheet" href="non-critical.css">
</noscript>

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

</head>

<body>
    <!-- visible content goes here -->
</body>
</html>

Resource Hints

But wait, there's more!

Limiting the render blocking effect of CSS and JavaScript resources with progressive, priority-oriented loading is a critical stride to maximize loading speed, but there's one more step we can take.

HTML resources hints can help to get a jumpstart on any needed 3rd-party network connections and strategically pre-load other critical resources like custom fonts and above-the-fold images.

What are resource hints like preconnect and preload? Learn how to leverage a few simple lines of HTML for an important page speed improvement:

Resource Hints