Building a performant website
Using as much managed services as possible
For one of our clients we got the request to build a brand new public website which will combine their own content together with videos and data insights from their partners. This needs to be a performant and SEO friendly website where we needed to take into account the different data providers.
In this blogpost I’ll give a quick overview of the chosen systems and the reason behind it.
Architecture overview

Cloudflare
We mainly use Cloudflare to protect our website and manage the DNS easily. However Cloudflare has a lot of additional features, which we used extensively within the project. Cloudflare introduced Cloudflare access, it allows us to define user groups that can have access to certain websites. This removes the need for a VPN or a whitelisted ip address and gives us so much flexibility.
Another feature which is quite powerful is the ability to cache on the edge by specifying correct cache-control headers on the origin server. This prevents unnecessary load on the server and gives a fast user experience for visitors of the website without having a complex caching infrastructure setup.
NextJS

To have a performant & SEO approved website without leaving the React ecosystem, you immediately come to a framework like NextJS. It allows you to have both server-side-rendering(SSR) and client-side-rendering (CSR). We rely heavily on CSR because a lot of the data from our client is dynamic coming from multiple sources. This constraint pushed us in going for a SSR with (Re) Hydration method as it is called in “Rendering on the Web”.

Downsides of using NextJS is slow TTFB which can be solved by our Cloudflare caching.
Additionally TTI >>> FCP, we need to ensure that the bundle size is slow to lower the TTI.
We had some issues with MomentJS (which is quite heavy when bundled into the base bundle of our website). Additionally we ditched Apollo Client for a more lightweight client like the default library “fetch” included with NextJS.
DatoCMS

The website is powered by a headless CMS, which we chose DatoCMS. It has a great back office system to easily manage your content and assets, where they heavily rely on Imgix for image processing and Mux for video processing. It has a GraphQL API that we can use to retrieve all the relevant information in one query. You can even explore the API with the Graphiql explorer built-in to the back office system.
They also have a React library to easily create responsive images and support SEO.
We also love the fact that you can easily preview your website in draft mode via the draft CDA endpoint. This was easily implemented with the preview functionality of NextJS.
Apollo Server

Besides the content coming from the DatoCMS CDA. We have an Apollo server that is connected to a REST API. The API is coupled with the Apollo server via the data sources library. It gives us out-of-the box caching and allows us to transform the data to the respective format required by the GraphQL schema. The client on the other hand can explore the GraphQL API within the playground or can work type safe via the Graphql Code generator.
Google Cloud Platform

The infrastructure stack is quite straightforward. We have Cloud Run for all our computing services which uses the Docker images from Cloud Registry. Cached data resides within a Redis instance. At the moment we don’t make use of the Cloud Memorystore because it’s incompatible with Cloud Run.
In the background we have some Cloud functions combined with Cloud Storage and Pub/Sub to support some imports, monitoring and scheduled tasks.