Angular initial render speed and ‘above the fold’ content

Marko Lekić
Fleka Developers
Published in
5 min readJan 17, 2017

--

There are usually static elements in your HTML that you can pull out of render blocking javascript to give visitors the impression of a faster page loading. We will add some static elements from Angular templates directly to index.html so they can be displayed before your Angular app renders.

The reason for doing all of this is that initial loading speed has become a very important factor in visitor’s decision to stay on your website. Some surveys suggest that many visitors leave websites that take more than 3 seconds to load. When you’re making a website as an Angular single page application, you know it’s very hard to achieve a full render of your website in 2 seconds or less (I would argue it’s impossible without any server side rendering and caching). However, showing at least a piece of your website in that time can give the impression of a much better load time. There are some tricks that can be used to show ‘above the fold’ content before your Angular code is fetched and views rendered.

NOTE: I’m running examples of code on a simplified version of a page from our company website https://www.fleka.me. I’ll show the thumbnail images generated by Chrome Developer Tool’s timeline. To simulate real world environment I disabled caching and set network throttle to “Good 3G”. This allows me to better see the differences between approaches.

The usual Angular way

We see this, or a similar version of it, in most of Angular application root html files:

<!-- index.html -->
<div class=”root”>
<header ui-view="header"></header> <main ui-view></main> <footer ui-view="footer"></footer></div>

Until your app’s main .js file is fetched from the server and Angular is initialised your visitors see a blank page. This means that JavaScript is blocking the render of your page. While this may be ok for web applications, it’s not acceptable for websites.

Let’s start with a simplified example of pulling out a logo, as that is usually just an image or an anchor element that doesn’t depend on the data from an API or another data source.

Extract the code for displaying the logo

If you consider index.html file from above and we have this in our header template:

<!-- header.html -->
<div class=”navbar”>
<div class=”navbar-header”>
<a class=”logo”></a>
</div>
<div class=”collapse navbar-collapse”>
<! — Menu code here →
</div>
</div>

We’re going to see a timeline similar to this:

We see here that ~2.7 seconds pass until our visitor sees something happening on the page.

Now, let’s pull the code for displaying the logo out in index.html:

<! — index.html →
<div class=”root”>
<header ui-view=”header”>
<nav class=”navbar”>
<div class=”container”>
<div class=”navbar-header”>
<a class=”logo” ui-sref=”home”></a>
</div>
</div>
</nav>
</header>
<main ui-view></main> <footer ui-view=”footer”></footer></div>

You’ll notice that I only pulled out the code for the logo, I left the code for the menu in header.html. Your header.html can still stay the same, because when Angular loads it will render that and replace the code that you have inside <header ui-view=”header”> in index.html.

Ok, running this gives us a timeline like this:

Much better. We see here that the first time the visitor sees something happening on the website is at ~550 milliseconds. They will not see the actual content until Angular loads and renders it, but this gives them the impression that the website is responding quickly.

Replacing logo .png with base64 encoded string

You’ll notice in the last timeline screenshot that we first see the red line that is the header’s border, and then we see the logo. This is because the logo is a .png image and needs some more time to be loaded. We can slightly improve this by setting a logo to be a base64 encoded string, which means that it’s already there when our css file arrives and doesn’t have to be fetched (you can Google how to transform image from png to base64, but if your images are not small and simple it’s better to avoid this)

With this slight modification we finally achieve this:

So now we have an improvement of ~2 seconds in displaying the first piece of content on our website. Going back to the survey from the beginning of the text, this is a big plus.

More options

When you start playing with this approach, you can continue by extracting the code of your menu too (if it’s static and not fetched from an API or something like that, of course).

An interesting approach would be to display header in the correct size, color, with correct borders, … and then let Angular populate it with the data for the menu or anything like that later on. If you have a sticky footer, you can display that one too before Angular loads.

The step after all of this could be to extract the basic style for initial static data from your .css files and put them directly in the <head> element. Then you can load your css files asynchronously, which means they won’t block the render of the content from your index.html file, which will give you even faster load times then what we achieved here. This depends very much on the website you’re working on, because this could mean that, for example, you have to mimic some of Bootstrap’s styles, which can get pretty messy considering you have to worry about different screen sizes.

--

--