How did I improve the website performance score from 35 to 100?
Tags: webdev, google, firebase, performance
Published: 2023-05-26 16:20:31


As you may know, not long ago, I started my personal blog. Instead of opting for the traditional route of using the popular WordPress CMS for blogs, I decided to embrace new technologies. My choice landed on Next.js and a NoSQL-type database. 

![Website Performance on Ubuntu server](https://proflead.dev/assets/blog/website-performance-score/how-did-I-improve-the-website-performance-score-from-35-to-100.webp "Website Performance on Ubuntu server")

**In this article, I cover:**
- Why I chose Next.js and a NoSQL database
- Hosting Platform for Next.JS Project
- Low performance of the initial deployment
- Steps I took to improve performance
- Magic formula to get 100 score



## Why I chose Next.js and a NoSQL database
During my development, I asked myself, "Why did I choose the harder path?" Launching a Wordpress blog takes just 15-30 minutes. However, there are several reasons why I selected this tech stack.

### Why Next.JS

1. **Improved Performance**: Next.js offers server-side rendering (SSR) and automatic code splitting, resulting in faster initial page loads and better overall performance.
2. **SEO-Friendly**: With SSR capabilities, Next.js enables search engines to crawl and index your website effectively, improving its search engine optimization (SEO).
3. **Simplified Routing**: Next.js provides a straightforward routing system, making it easier to handle complex routing scenarios and create dynamic routes.
4. **React Ecosystem Integration**: Next.js seamlessly integrates with the React ecosystem, allowing developers to leverage existing React components and libraries, saving time and effort.
5. **Serverless Deployment**: Next.js supports serverless deployment, making it effortless to scale and deploy your application to various platforms.

### Why NoSQL Databases
1. **Flexible Schema**: NoSQL databases offer a flexible schema, allowing for easy adaptation to evolving project requirements without strict data structure constraints.
2. **Scalability**: NoSQL databases excel at horizontal scalability, meaning they can efficiently handle high data volumes and traffic loads as projects grow.
3. **High Performance**: NoSQL databases are designed for fast read and write operations, making them suitable for applications requiring real-time data processing or large-scale data retrieval.
4. **Handling Unstructured Data**: NoSQL databases are well-suited for handling unstructured or semi-structured data types, such as JSON, making them ideal for projects dealing with diverse data formats.
5. **Distributed Architecture**: NoSQL databases typically employ distributed architecture, ensuring data redundancy and fault tolerance, which enhances reliability and availability.

## Hosting Platform for Next.JS Project

Since my blog was ready, I had to find a hosting solution. Initially, I decided to use my virtual server as it seemed sufficient for a simple blog, and I didn't explore other platforms. 

Setting up everything on Ubuntu server proved to be a bit challenging, but I managed to get my blog up and running. If you're interested in learning how to deploy a Next.js project on Ubuntu, let me know. 

However, my joy was short-lived. When I checked the performance using Lighthouse, I was shocked to see the scores: 35 for mobile and 55 for desktop. It was definitely not the outcome I had anticipated.

![Website Performance on Ubuntu server](https://proflead.dev/assets/blog/website-performance-score/pagespeed-insight-desktop.webp "Website Performance on Ubuntu server")

![Website Performance on Ubuntu server](https://proflead.dev/assets/blog/website-performance-score/pagespeed-insight-mobile.webp "Website Performance on Ubuntu server")

## Low Performance of Initial Deployment

I began investigating the cause of the slow performance and soon discovered that the issue lied with **Server-Side Rendering (SSR)**. 

**SSR** is a web development technique where the server generates the HTML content for a web page and sends it to the client. The server processes the request and dynamically renders the page with data, styles, and scripts, delivering a fully rendered HTML page to the client. 

Unfortunately, my Ubuntu server lacked the necessary power to handle this task, resulting in sluggish performance.


## Steps I Took to Improve Performance

### Static Site Generation (SSG)

I started thinking about what I could do with the current server to make loading faster. The good thing for me was that Next.js supports many types of rendering, including **Static Site Generation (SSG)**. You can learn more about it here: [https://nextjs.org/learn/foundations/how-nextjs-works/rendering](https://nextjs.org/learn/foundations/how-nextjs-works/rendering).

**Static Site Generation (SSG)** is a method of generating static HTML pages at build time, rather than dynamically rendering them on each request. In SSG, the website's content is fetched and rendered during the build process, resulting in a collection of static HTML files that can be served to clients.

During the build, the static site generator pulls data from various sources, such as markdown files, APIs, or databases, and compiles it into HTML pages. These pages can include dynamic data and interactive components, but the rendering occurs beforehand, allowing for faster and more efficient content delivery.

The generated static files can be hosted on a simple web server or a content delivery network (CDN) without the need for server-side processing. This approach offers several benefits, including improved performance, enhanced security, and reduced infrastructure costs.

To build the static version of my Next.js project, I made adjustments to a few files: **package.json** and **next.config.js**.

In package.json, I added the following code to the script section:

```
"build": "next build && next export"
```

In next.config.js I added the following code:


```
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
  images: {
    unoptimized: true
  }
};

module.exports = nextConfig;
```

**Please note that if you omit the images unoptimized code, you'll encounter an error.**

To generate the static website, simply run the following command in your terminal:
```
npm run build
```

or 

```
yarn run build
```

Depending on your package manager. The static website will be generated in the **"out**" directory within your project. From there, you can copy it to any hosting platform, and your static website will be live.

The static version of my blog helped me improve performance for desktops from **50 to 86** on my Ubuntu server and for mobile devices from **38 to 69**.

![Static Website Performance on Ubuntu server (Desktop)](https://proflead.dev/assets/blog/website-performance-score/desktop-score-for-static-ubuntu.webp "Static Website Performance on Ubuntu server (Desktop)") 

![Static Website Performance on Ubuntu server (Mobile)](https://proflead.dev/assets/blog/website-performance-score/mobile-score-for-static-ubuntu.webp "Static Website Performance on Ubuntu server (Mobile)")

### Optimize images
Optimizing images was the next crucial step. Instead of using traditional formats like **JPG** or **PNG**, I converted all images to [**WebP**](https://developers.google.com/speed/webp) format and reduced their resolutions. I chose WebP because it is a web image format developed by [Google](https://google.com) specifically designed to optimize web performance.

**WebP** utilizes a combination of lossy and lossless compression techniques to reduce file size while maintaining high image quality. By reducing file sizes, WebP images contribute to faster loading times and reduced bandwidth usage. Additionally, WebP supports transparency, making it suitable for images with transparent backgrounds, and it also enables animations. Being supported by modern browsers, WebP offers a compelling solution for web developers aiming to enhance web performance, deliver visually appealing content, and optimize user experience.

This optimization technique helped me improve the score for mobile devices, although it wasn't sufficient to reach a score of 100.


### Hosting Platform
Even for serving static files, the server plays a crucial role in content delivery. Therefore, I made the decision to migrate my project to Firebase. 

Once I made this transition, my score increased to 100 for both mobile and desktop devices.

![Static Website Performance on Ubuntu server (Desktop)](https://proflead.dev/assets/blog/website-performance-score/mobile-score-firebase.webp "Static Website Performance on Ubuntu server (Mobile)") 


## My Magic Formula to Get 100 Scores

As you can see, my magic formula is quite simple: **Next.js + WebP + Firebase = 100** ;)

Even if you don't use Next.js, you still have a chance to improve your score. 

**There are four main factors that can help you achieve this:**

1. Hosting platform
2. Technology you use
3. Valid, semantic, and properly structured HTML, CSS, and JS code
4. Correct size and format of your images

In my upcoming articles, I will show you how to deploy your project to Firebase and **utilize this platform for free**.

Stay tuned! ;)

Source: [https://proflead.dev/posts/website-performance-score](https://proflead.dev/posts/website-performance-score)