Prioritizing Above the Fold Content with JavaScript and HTML Templates

Published

We can now differentiate between content that is Above the Fold (content that is visible immediately when a page loads) and Below the Fold. Forcing the browser to load Above the Fold content first will result in quicker page load times and a better user experience 1.

Highlighting “The Fold” on my homepage, appearing at the bottom of a 100vh Hero Image

Instructing the browser to load Above the Fold content first can be done in two parts:

  1. Outputting Below the Fold Content into a HTML Template Tag – This ensures content is still available in the browser, but is not rendered onto the page. Any images or referenced media in the content will not be requested by the browser until the template is activated 2.
  2. Activating Template once Above the Fold content has loaded – set a JavaScript event listener to fire when Above the Fold content is ready. The event callback will “activate” the Template by moving Below the Fold content out of the template and placing it elsewhere in the DOM.

Staging Content inside an HTML Template

Pretty powerful and easy to use, the <template> tag allows you to park HTML content in the browser/front-end until it is needed. While the HTML is parsed and added into the DOM, the browser will not make any requests for referenced images, scripts, etc. until the content is moved or copied outside the <template> tag.

Here is an example template which includes an example of content being rendered by a PHP WordPress back-end, as well as an example JavaScript <script> tag.

<!-- Sample Template which can contain any standard HTML elements -->
<template id="homepage-delayed-content">

  <section id="about-me">

    <!-- Example of content output via PHP -->
    <?php while ( have_posts() ) : the_post(); ?>
      <?php the_content(); ?>
    <?php endwhile; ?> 

  </section>

  <section id="homepage-photos-container">

    <ol id="photos-list">
    </ol>

    <!-- Example script tag -->
    <script type="text/javascript">
      alert('this javascript will not execute until the template is activated!');
    </script> 

  </section>

</template>

This template tag can be placed anywhere within the Document Body, ideally after any Above the Fold content and it’s required CSS / JavaScript.

Activating the HTML Template Content with JavaScript

Now for the fun part: using JavaScript to detect when the Above the Fold content is finished loading. Once it is ready, the JavaScript needs to activate the Below the Fold content staged in the HTML Template.

In our example, a hero image occupies the entire browser viewport height at the top of the page (making up all of the Above the Fold content). The JavaScript event listener will fire once the hero image has loaded, and “activate” the staged content in the Template Tag by moving it out of the <template> element and placing it elsewhere into the Document Body.

const loadedImage = new Image()

// set onload event listener to fire when image loaded    
loadedImage.onload = () => {
  // move Below the Fold content from template into document body
  document.body.insertAdjacentHTML('beforeend', document.getElementById('homepage-delayed-content').innerHTML)
}

// tell browser load the image (by setting img src)
loadedImage.src = '/img/homepage/hero-carousel/IMG_3872-1400x1050.jpg'

Performance Considerations

I’ve read that cloning nodes out of the Template Tag may be better performance-wise than copying the inner HTML as shown above 3. Here is an example of a JavaScript snippet that clones the nodes instead:

const templateNode = document.getElementById('homepage-delayed-content')
const templateContentClone = templateNode.content.cloneNode(true) // perform a deep copy
document.body.appendChild(templateContentClone)

References

  1. Reduce the size of the above-the-fold content
  2. HTML’s New Template Tag, Standardizing Client-side Templating
  3. Deep cloning vs setting of innerHTML: what’s faster?

Comments

Loading comments..

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *