Building a high performance website in 2023. 🚀
Tags: webdev, webperf, fullstack, tutorial
Published: 2023-11-03 17:46:46

A few weeks back, I decided to give my personal website a fresh makeover. My main objective was to **establish a benchmark in terms of performance, accessibility, and Web Vitals scores**. It took me some late nights, but I am pretty satisfied with the result.

In search of the perfect framework for the job, I first tried out [NextJS](https://nextjs.org/) and [Nuxt](https://nuxt.com/), however the first results I got were discouraging. Namingly there was a considerable amount of JS being shipped and it didn't look like I would be able to make it close to scoring 100 in the [PageSpeed Insights](https://pagespeed.web.dev/), which was my ultimate goal.

_Eventually I joined the [Astro](https://astro.build) hype and went for the latest release (v3.4.3) on the frontend and [Strapi](https://strapi.io/) (v4.14.5) on the Content Management side._ 

Why Astro? For 3 reasons:
⭐ Astro renders the entire page to static HTML, removing all JavaScript from the final build by default. **100% Static HTML, No JS**.
⭐ On-Demand Components: You need some JS? Astro can automatically hydrate interactive components when they become visible on the page. If the user never sees it, they will never be loaded.
⭐ It follows a Bring Your Own Framework (BYOF) approach: You could basically build a site using React, Svelte, Vue, Preact, web components, or just plain HTML + JavaScript. Perfect for my case, since I wanted to reuse some Vue components from my old website.

As it turns out, Astro enables developers to combine astro components with components from other frameworks. For instance these are the components I used for my website:

![Astro components structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ug12wnbm0asogfubwrkk.png)

As you can see, since in my case the portfolio and FAQ pages contain a lot of interactivity, I decided to render these 100% on the client. Below is the `faqs.astro` page, which renders the related Vue component, client-only.

![Astro page, example including a Vue component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5353mnxhwksrhmjjk7g.png)

The wrapping layout is the same like in any page and it is server side rendered by Astro, while the content of the page will be rendered on the client's browser by Vue. Note that you could do the same, using components from all the [frameworks that Astro supports](https://docs.astro.build/en/core-concepts/framework-components).

Some other things I really liked about Astro were the tooling, the documentation and the built-in Astro components like `<Image>` and `<Icon>`. The `<Image>` component can transform, optimise and bundle the images for you.

```html
<Image src={localBirdImage} alt="A bird sitting on a nest of eggs."/>
```

On the other hand, the `<Icon>` component enables the developer to use icons from popular libraries like Material Icons and Fontawesome without having to deal with the hassle of importing their resources and finding a way to load them efficiently.

```html
<!-- Automatically fetches and inlines Material Design Icon's "account" SVG -->
<Icon pack="mdi" name="account" />
```

When it comes to managing content, Strapi is my favourite open-source, NodeJS based, Headless CMS, giving me the flexibility I need in terms of content management, filtering and querying. By the way, while building the queries for the individual pages I discovered its [Interactive Query Builder](https://docs.strapi.io/dev-docs/api/rest/interactive-query-builder), which helped me a lot.

The Astro website was deployed on Netlify and the Strapi instance on an EC2 host on Amazon Web Services (AWS).

![PageSpeed Insights of my Astro website](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s41lz69icrrmvxzq41lz.png)

You can check out my website under [dimeloper.com](https://www.dimeloper.com)

Overall, I had one of the smoothest experiences I ever had with a new framework, so I hope that this post will encourage more developers to start using Astro.