Personal website performance optimization
Tags: javascript, performance
Published: 2022-03-25 07:19:03

> [Publish a new personal website](https://blog.rxliuli.com/p/26b63c066b424d77b36ca51ff44734eb/)

I released a new version of my personal website two days ago, but at that time there were still some unresolved performance issues, including

- Performance optimization
  - Reducing the number of dependencies
    - Chopping off runtime dependencies marked
  - Compressing image sizes
  - Adding .nojekyll to avoid github actions doing unnecessary builds
- Validation tools
  - rollup-plugin-visualizer: check bundle size
  - lighthouse in chrome devtools: test runtime performance

## Validation tools

To do a good job, you have to have a good tool. I use two main tools to test and validate optimizations

### rollup-plugin-visualizer

> [npm](https://www.npmjs.com/package/rollup-plugin-visualizer)

This is a dependency analysis tool integrated into rollup that will analyze how my code relates to the dependencies in the bundle, which is important to find out which dependencies need to be optimized.

![1648171955116](https://blog.rxliuli.com/resource/ee33937feba94bdba082777ca1591242.png)

### lighthouse

> [online version](https://web.dev/measure/)

This is a self-contained feature of chrome browser, it can check out the problems of web pages, including blocking time, oversized images and other problems are checked out by this tool. The following is the test result of v1 version, the performance is simply miserable, so v2 I focus on solving these problems.

![1648172483272](https://blog.rxliuli.com/resource/a06ce4d48ea54974afd92a793771dcac.png)

## Performance optimization

### Reduce the number of dependencies

Since the site was updated from v1 => v2, reducing the number of dependencies has been a key concern for me

v1 has few direct dependencies, only 9, but many more actual dependencies (node_modules black hole), 133 after de-duplication

- @fortawesome/fontawese-free 6.0.0
- @liuli-util/react-router 0.3.1
- mockjs 1.1.0
- normalize.css 8.0.1
- rc-util 5.18.1
- react 17.0.2
- react-dom 17.0.2
- react-markdown 8.0.0
- react-use 17.3.2

v2 had only 3 runtime dependencies when the site was last released, the first one I cut was react, it was too big for small projects, classnames was kept because it was a 1kb utility function and needed to be used frequently, and marked was the smallest and most popular markdown parser that I needed to render some markdown snippets.

- preact
- classnames
- marked

But marked is still a big part of it, about 58%, and more fatally, it's a cpu-intensive operation that makes the TBT reach 510ms, which is obviously something I need to work on.

![1648170006760](https://blog.rxliuli.com/resource/f8e89fe7853c4b27abed09500f2e1fa1.png)

Before looking at the original project [bchiang7 v4](https://github.com/bchiang7/v4), I also considered using a plugin to convert markdown to html at build time to avoid performance loss at runtime, but of course considering that small markdown fragments don't seem convenient to split into separate markdown file, so I didn't implement it. But that's what the original project did, so I put it into practice -- it was surprisingly easy, since there were only two markdown fragments to handle, so I easily solved the problem with [vite-plugin-markdown](https://www.npmjs.com/package/vite-plugin- markdown) to solve this problem.

Now it's a 100 out of 100 on mobile devices too!

![1648170247717](https://blog.rxliuli.com/resource/602265903cd2468f88c8a8e0c5f05891.png)

The final bundle size was reduced from 2.18M to 58.96k, which did pretty much meet my expectations.

### Compressing the image size

I didn't pay much attention to the image before, but after checking it with lighthouse, I compressed it using [Squoosh](https://squoosh.app/). The reason I didn't use the build tool plugin is that there are not many images, and the build tool is good for batch processing but not for fine tuning, e.g. some images need to be compressed and then resized.

![1648172958949](https://blog.rxliuli.com/resource/fcc0980342964b2aa027ea6602efecd2.png)

- 28 => 19
- 196 => 56
- 103 => 28

Overall the image size is optimized by 68% and lighthouse no longer reports that the image needs to be optimized.

### Add .nojekyll to avoid github actions doing unnecessary builds

I was motivated to do this because I noticed that the deployment of github pages was slowing down, and sometimes I couldn't see it in github deployments when I pushed it up, which made me feel a bit strange, so I checked it out and found that gh-pages deployments now go through the github actions process, which actions is divided into two steps: **build => deploy**.

![1648173439512](https://blog.rxliuli.com/resource/41666da23fc249e59645c911aa01217d.png)

And in the build step, github will use jekyll to build by default

![1648173643373](https://blog.rxliuli.com/resource/3654ef229bf64994a66e6779bd3f0df9.png)

This slows down the release a bit, so I added .nojekyll to bypass this step

![1648173684396](https://blog.rxliuli.com/resource/5d39c7c5c88b49e0ad01353876d8dcbf.png)

As you can see, this reduces the build time by over 50%, and every future release will benefit from this.

## Wrap-up

There is no end to performance optimization, from chrome v8, which greatly optimizes the performance of js, to the programming language of build tools from nodejs to golang/rust, to even vue authors who are not satisfied with webpack to create vite on their own, all prove this, and I'm just trying to do something for my personal website.