I've rebuilt my portfolio. Now it loads in less than 1 sec! Here's how I did it! ⚡
Tags: showdev, javascript, webdev, react
Published: 2021-01-11 17:00:49

Some time ago, during my early **PHP** years, I had created a website for myself, which combined my resume and some space for sharing my thoughts with the world. That website was well designed and had many features like tagging posts, filtering, and searching. But on the other hand, that website was cumbersome. The application took about **5 to 6 seconds** to load on a good internet connection!


![Bad Lighthouse](https://i.ibb.co/cYKVpfn/report-numbers.png)


I realized that at some point, I would need to rewrite everything from scratch. That moment came when I have learned about the **React** ecosystem. Now, after it's done, I would like to share my thoughts on how I have managed to make the website incredibly fast. 


>**Note**: When writing this article, I intend to explain what can be done to improve any website's performance. Please note that some of those points may not be valid for your use case since not all websites are the same (blog is different than e-commerce application).


## Use the right tools for the job 🔨


**PHP** language was fantastic, as so **Laravel**, which is a framework for developing web applications. But after I have learned the **React** and its ecosystem, I have decided to go with **NextJS**. And oh, boy, it was an excellent choice! **NextJS** supports two forms of rendering your content:


* **Static Generation**: The **HTML** is generated at build time,
* **Server-side Rendering**: The **HTML** is generated on each request.


Static generation is perfect for use cases like blogs or personal websites, where the content does not change often. After you build the application with that approach, you end up with a bunch of static **HTML** files, which you can deploy on any hosting. And nothing is more performant than simple **HTML** files.


## Optimize your assets 📦


It seems like an obvious thing to do, but I will mention this anyway. Any static assets that you use on your website should be optimized. It includes minifying your **CSS** files and **JavaScript** files but also compressing images. For example, if you use a picture for your avatar, you don't need a file that has **500x500px dimensions** and a weight of **200 Kb**. Choose a resized file instead.


>**Tip**: Almost any image can be optimized by dropping its quality to about **80%**, and there will be no visual difference between the compressed version and the original.


If you use modern web frameworks like **NextJS**, all of your bundles are already optimized. But be careful if you put external stylesheets or scripts to your website because they are not always minified.


## Preload external scripts 🕖


When dealing with external **JavaScript** files, you need to be careful where you put those scripts inside your **HTML** because this will affect the loading time. By putting external scripts in the head of the document, your browser will try to fetch and execute the script before rendering **DOM**. It is recommended to move external scripts at the end of the body or specifying defer property on those scripts.

Deferring scripts will result in them being downloaded with other resources but executed after the **HTML** is parsed and rendered. I recommend you to read this excellent article on that topic: [Efficiently load JavaScript with defer and async](https://flaviocopes.com/javascript-async-defer/)


## Lazy load images 🖼️


We tend to use a lot of images on our websites. Whether they are put in the background, or we want to share something, it's unnecessary to load them all at once.  The standard way to deal with images is to load only those directly in the viewport or close to it. We don't need to load an image that is far down the page and isn't visible to the user yet.

There are many techniques to implement lazy loading, but the most common way is to use the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) or a library that depends on it. Recently, native lazy load support has been added to the **Google Chrome** browser. It is as simple as adding a **loading** property onto the **img** element.


```html
<img loading=lazy>
```


Not every browser yet supports it, but this will be the standard of lazy loading images in the future. You can learn more on that here: [Browser-level image lazy-loading for the web](https://web.dev/browser-level-image-lazy-loading/)


## Use service worker 📝


A Service Worker is a script that executes in the background, in a separate thread from the main **JavaScript** bundle. A service worker can intercept all network request, so it's often used for caching assets and some of the critical API payloads that make possible for a website to function without an internet connection.

Using the **service worker** will not increase your website's speed on the very first load, but every other reload will be faster since some of the assets are already downloaded and stored inside the browser's cache. 


>**Note**: A service worker is recommended for the browsers to treat your application as an installable **SPA**. 


## Use CDN 🌎


A **Content Delivery Network** is a way to deliver content from your website to clients more quickly and efficiently, based on their geographic location. It allows for the quick transfer of assets needed for loading your content, including **HTML**, scripts, and stylesheets from the server located closest to the client.

The main benefits of using a **CDN** in front of your web server or static hosting are:

* **Improving website load times**, because the website and its assets are cached and served from the closest server in the network,
* **Reducing bandwidth costs** since requests are interested and not directed to your server.


Many **CDN** providers (e.g., **Cloudflare**) provides you as well with security improvements for your application. They support you with a free **SSL** certificate for your domain and with protection from **DDoS attacks**.


## Effect? Blazing fast website ⚡


After developing my new website and implementing all of the tips listed above, I have reduced the loading time to about **1 second**! The effect had shocked me positively. Check out the lighthouse report:


![Bad Lighthouse](https://i.ibb.co/f9chbCJ/Przechwytywanie.png)



I realize that those numbers come only from a simulation, and they may differ on real devices. But seeing that audit with the **time of First Meaningful Paint being 0.7 seconds** makes me smile. 😀

Thanks for reading, and I hope you have enjoyed this article. I would love to receive your feedback on my portfolio site since it is new and freshly designed. Check it out, and let me know your opinions. 😊


**My portfolio**: [blog.jskoneczny.pl](https://blog.jskoneczny.pl/)

{% github Skona27/fancy-portfolio no-readme %}


**PS**: If you are interested in the latest tech news, you can follow my account since I plan to post here regularly. I also tweet on a regular basis so that you can follow [My Twitter account](https://twitter.com/SkonecznyJakub) as well!