Recently, Google told us that some of our URLs of our poll maker could use performance improvements in their Core Web Vitals.

Google use their Core Web Vitals to measure how user-friendly a page is and they are taken into account when ranking their search results. Because we want to be found via Google and don’t want to spend our time advertising our platform from door to door, we decided to do something!

We noticed our FCP (First contentful paint) value was too high with 2.4s. It is considered GOOD below 1.8s, at least it was not POOR.

FCP

Why the FCP of a page is too high can have many reasons. For instance:

  • Long Time to first Byte (TTFB), by slow routing or slow server response time
  • Excessive DOM size, i.e. there are too many elements, or they are nested too deep
  • A lot of static assets like styles, javascript are required for the initial page load

We checked or TTFB value from different locations and it seemed alright with around 100 - 200ms. Our setup consists of a Rails backend served at Digital Ocean with server side rendered templates and our assets are served from S3 buckets through AWS Cloudfront. For most of our landing pages the requests for the rendered html take less than 50ms. So where does all this extra time go?

Sure we are using plenty of javascript libs like jQuery, which delays page loading significantly. Because we cannot just dump these dependencies, we first tried to tackle the problem from another angle:

Improve FCP with a static cached page

We uploaded a snapshot of a rendered page to S3 and also serve it through Cloudfront. Here we had an FCP of 1.4s, Great! 1s less than before.

With a solution in sight, we cheerfully worked our way through the abysses of AWS configuration. So we changed our setup, so that our DNS points directly to Cloudfront. In the behaviour we configured that certain landing pages are served from S3 and the rest from our Digital Ocean Rails backend.

After everything was in place, we were excited to measure our performance with Lighthouse. And …

Surprise

FCP: 2.3s

Yes! Or No! That’s not good. Refresh Lighthouse, this must have been an outlier. But again:

2.2s
2.4s
2.3s
...

It did not work. But why? After some time we figured out, what the only difference was:
We served the page from the top level domain pollunit.com and the assets from a subdomain assets2.pollunit.com, both serving static content from S3 buckets.

In our previous experiment the page and assets both were served from assets2.pollunit.com. So it seems the lookup of an additional domain takes some extra effort and is therefore penalized in Lighthouse.

In your HTML head you can add a preconnect hint like:

<link rel="preconnect" href="https://assets2.pollunit.com" crossorigin />

In theory it helps the browser to early setup connections to other hosts, before requests are sent. In practice, this did not affect our performance.

Serve everything from one domain

So we changed our Cloudfront setup, so that everything was served through our top level domain pollunit.com. And Yes! Finally we got the FCP down to the desired 1.4s.

Interestingly, we have also found out, that when we did not serve content from S3, but rendered from our backend, the performance was with an FCP of around 1.7s better than serving cached static content from two domains.

Our key takeaway was:

=> Reducing your used domains, saves you a lot of performance. In our case significant 0.7s. <=