DEV Community

Cover image for I've rebuilt my portfolio. Now it loads in less than 1 sec! Here's how I did it! ⚡
Jakub Skoneczny
Jakub Skoneczny

Posted on

I've rebuilt my portfolio. Now it loads in less than 1 sec! Here's how I did it! ⚡

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

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

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 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.

<img loading=lazy>
Enter fullscreen mode Exit fullscreen mode

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

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

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:

GitHub logo Skona27 / fancy-portfolio

My new fancy portfolio

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 as well!

Top comments (16)

richtone profile image
Richard Turza • Edited

Two non-technical things if you would like.
1) Don't use star rating, or any other kind of rating for your knowledge and expertise. It's just not telling anything meaningful.
2) If you are using a photo, use one where it's possible to recognize your face.

skona27 profile image
Jakub Skoneczny

Thanks for that advice! I will plan to get rid of those star ratings and put my example projects instead :)

matjones profile image
Mat Jones

Man, Next.js is freaking amazing.

marceliwac profile image

Great stuff Jakub! Don't forget to add a favicon for that cherry-on-top feeling to your website. Your blog looks great1

skona27 profile image
Jakub Skoneczny

Thanks! I've just added a favicon :)

laviku profile image

That is great, congratulations on that. I like that you said that every website is different hence needs different optimization steps.

zarszz profile image
Ganjar Gingin Tahyudin

can you give information where i can running test like that ??

skona27 profile image
Jakub Skoneczny

Of course! The auditing tool is called Lighthouse, and it is available for you in the tab inside the Chrome DevTools. You can read more information about it on its official website:

codecustard profile image
Emmanuel Barroga

Awesome article! What are your thoughts on using webp file format?

skona27 profile image
Jakub Skoneczny

WEBP format allows to significantly reduce the size of images when comparing with, e.g. JPEG format. But of course, it is not supported by old browsers like IE11. So if you have to maintain old browser support, then don't use web 😀 In any other way, go with it!

ezio1404 profile image
EJ Anton Sabal Potot

Base on what I read you can use picture html tag for creating fallbacks for older browsers

cdthomp1 profile image
Cameron Thompson

This looks great! I would check your speeds with the network settings in the developer options in chrome. I had a slower network and it loaded a little slow. Overall, great work!

skona27 profile image
Jakub Skoneczny

Yes, it may vary depending on the internet connection. While doing those audits, I didn't throttle my internet speed :)

shadowtime2000 profile image

If you use NextJS you can do a React -> Preact aliasing on the client bundle so it cuts down on size by a lot

tochi06814091 profile image

Your portfolio website does not have media files( images, videos ). If it does, those metrics won't look pretty.

skona27 profile image
Jakub Skoneczny

Yes, that is true that I don't have much media on my website. But if I had, it doesn't necessary mean that performance would go down. Images and videos can be lazy-loaded once they go near the viewport so that they wouldn't affect the time for the first load.