In my career as a web performance consultant and especially since I do performance workshops for companies and dev teams, I often recognize the same with performance problems. No matter how big the team or the project was, after some time, the application or website suddenly started being slower.
If you like this article, smile for a moment, share it, follow me, check out my RSS feed and subscribe to my newsletter.
Often my customers hire me for helping them to find their performance bottlenecks and teach the dev team exactly how they can measure and fix the performance issues of their application or website.
To keep your site up to speed is no rocket science. You just have to follow some rules. But as I want to help all my customers with my very best knowledge I've done a field trial with my website, and in this post, I describe my way of making my site faster, what I did and why I did it.
I posted this article initially on my blog.
Tl;dr
The experiment is a field trial on how to improve the performance of your web page after the implementation is done. I want to speed up the page loading and the response time.
- What is a web performance experiment?
- What is the tech stack to be optimized?
- The progress of implementation
- Making my site fast using web performance optimization techniques
- Takeaways for web performance
- Next steps
What is a web performance experiment?
I am self-employed for many years, and I've worked on many projects with many different clients.
I worked as a web performance consultant, a developer, a technical project lead, a frontend architect or I was a dev team member additionally responsible for any performance issues, training or workshops and other performance-related topics.
Last year I had decided to take another step in my career and also offer web performance workshops for developers, dev teams and companies that are not related to my current projects.
So far, so good. I needed a new website, and I thought I needed it fast. To be fast is one of the most requirement of nearly any of my projects.
We, as developers should deliver fast and with high quality. That was the moment the idea of my "performance experiment" came to my mind, and I decided to try it.
I usually set up my projects, including a performance budget to have an eye on my speed and some more performance-related tasks. This time I made it different.
I said to myself. First, I am going to implement my website or better said my MVP. After that, I measure my performance, make a comprehensive analysis of the page speed and apply all the rules and optimization techniques I know to speed up my site. I wanted to face the same issues and problems my clients have.
In my workshops, we often pick some parts of my client's applications that are slow and fix them. Sometimes the stakeholder needs some functionality that is just not performant, but I like to show my workshop participants how they could fix these issues.
So this time I have to apply all the advice by myself, and I have to discuss with myself if some functionality is essential or if I can get rid of it.
I was inquisitive, and I started right away.
What is the tech stack to be optimized?
But what is the tech-stack? I went with GatsbyJs and my hosting with vercel/now. I decided against any content management system and just serve my GatsbyJs website with JSON files.
If you have ever developed a site with GatsbyJs and additionally have some React experience you know, it is pretty straight forward. In no time you have some pages with content on it.
ReactJs comes with much JavaScript for the production version. But I need to be fast. So I chose GatsbyJs.
The progress of implementation
After some pages and components, I had the first more significant task. I wanted to have a multi-language website. There are many useful plugins to help us with that, but none of them fit my needs to 100%, so I used Gatsbys hook functions to manipulate the page creation.
I translated the URL and passed a context variable as the language code (en
and de
). Manipulating the pages worked great with Gatsbys Node API, and I was motivated how fast I got to my first results.
Like I said above performance wasn't my number one priority and I didn't want to reinvent the wheel to safe time. So how can I save time while coding? Use libs instead of implementing the code yourself. So except for my translation implementation, I tried to use libs.
Which UI component library did I choose?
As I'm planning to hold web accessibility workshops in the future, I wanted to kill two birds with one stone. I searched for a React component library with full web accessibility. After some time, I found Grommet. I liked their style as well as their icons and decided to go for it.
State management on my web page
As I already work with redux, I didn't make some new researches and npm installed it to my GatsbyJs project.
Cookies-management
I need to inform my website visitors on how I collect data, and I need to allow them to decline any kind of tracking. As I need to remember their decision, I implemented react-cookie
.
Styling - CSS, CSSinJS, Scss?
I'm not getting comfortable with the way I can apply styles to React components, so I chose styled-components
for that as they were installed nevertheless via npm due to the grommet
and grommet-icons
packages.
Making my site fast using web performance optimization techniques
I am online! I was glad when I now --prod
my site to the web. I leaned back an enjoy it. So the first part of my experiment went well.
I have a website running. Now let's go for the exciting part of it. How fast is my site? I had no clue, so I needed to measure.
In my workshops, I use some lab or synthetic tools to measure and create detailed analyses, but I wanted to make the measurement as easy as possible. I decided to use four tools to measure. They must be free and available for all developers.
- Webpack Bundle Analyzer
- WebPagetest.org
-
Chrome Developer Tools
- incl. React Developer Tools
- Google PageSpeed Insights (Audit)
How to measure javascript performance?
Webpack Bundle Analyzer
To use the webpack bundle analyzer in GatsbyJs, I have used the gatsby-plugin-webpack-bundle-analyzer
plugin. It adds the additional webpack configuration to the build process so we can view it.
Let's run this and check out the results:
Ok as you see in the results of the webpack bundle analyzer, some libs I used are huge! All the libs are useful for me during the development, but in terms of performance, I might need to consider if I need them all. Some of them are important, while I probably can replace or remove others.
WebPagetest.org
WebPagetest.org is an excellent speed test tool to check the speed of your site. With the advanced settings, you can run multiple tests in different environments. For my website and the sake of simplicity, I ran three tests with various locations in the Chrome browser.
Chrome Developer Tools (Audit)
In this measurement, I focused on the results of the audit tab. If you want to dive deeper into the measurement with the developer tools sign up for my newsletter or check out my workshops for web performance.
To get a clear overview of my performance, I only check the performance and best practices checkboxes and run the audit with this setting. Keep in mind to use a new Chrome profile or at least an incognito window of Chrome to get more accurate results.
I took my latest build a ran it...
Oh my ... 😳
The "blazing fast site" I started with is nearly half as fast as before. Check out the screenshot below. Almost any metric is not in the optimal range.
I expected a slow result, but not that slow. I felt motivated, but before I started to speed up, I did one last measurement.
Google PageSpeed Insights
The measurement with the PageSpeed Insights from Google gives you an excellent overview of your performance metrics without having any developer knowledge. For the sake of completeness, I ran my site multiple times with the Insights-tool of Google.
How to make my site faster
After measuring my site with three tools, I created tasks based on it. I started with the results of the webpack bundle analyzer. I removed any default imports of libs.
If I only need on util function from lodash, I don't need the whole package in my bundle. When I saw the results, I recognize that Grommet is enormous. I still like the style of the components, but not the byte size.
So I implemented my components with a likewise style. This was probably the most work of all. Grommet does not only gives you some components, but it is also a whole theme. So every colour, font-size, border, padding of my site was defined by a theme object.
What I did was to keep the theme object and use all the defined values in my components but remove the "grommet" out of them.
After I removed Grommet, I rechecked my bundle and saw that styled-components
is still a dependency of grommet icons. So I could not just delete them. I don't like the way I can add styles to a component in React so I played a little with styled-components
and I loved it.
But before I used the lib, I checked the size and compared it to css
from the @emotion/core
lib. @emotion/core
was smaller at that time, so I removed styled-components, inlined my grommet icons with SVG versions and implemented @emotion/core
instead of styled-components
and React styles (note: I made this decision prior version 5 of styled-components).
Next, I saw that the main-thread work is to high. As I know and because the webpack bundle analyzer told me, I used redux for my state management.
I thought about this a while. Probably I don't need a library for my state management. I already have one: React
.
So I removed Redux and implemented it with Reacts context API. Not that redux is not suitable for any project; I just don't need it. After I removed unused code and libs, I started to went through my components. In nearly every component, I found some code I could remove.
Sometimes it was functionality for some fancy but not needed stuff; sometimes I could realize it on a different way with less code.
For my cookies, I used react-cookie
. I like the abstraction, but it still more code that has to run, and it is easy to implement a getter and setter for a cookie with plain JavaScript.
Results
In the meantime, I have optimized my site and get between 98% - 99% of the performance evaluations. It took me almost twice as long to apply all performance optimizations as it took to implement the website.
Takeaways for web performance
The takeaways of my performance experiment are simple to apply to future projects. Again as you read through my post, none of this is rocket science. You just have to follow some rules before starting and during your development.
- Set up a performance budget
- Check the bundle size of you libs
- Can I remove or reduce my code? Can I move it to a web worker?
- Making a site faster after you finished the development is much more complex than keeping the site fast from the beginning.
4. Next steps
If you like this article, smile for a moment, share it, follow me, check out my RSS feed and subscribe to my newsletter.
Cheers Marc
Top comments (6)
But the good news is, next time you will do it by default :)
Yes exactly. :D
That is the core of my post. And I knew what I was doing. I'm doing performance stuff for years. I assume it would otherwise have taken 4 or 5 times as long.
I was expecting a bit more about best practices to improve any javascript library performance.
Hey pulkit,
thanks for your replay. :)
Sorry to disappoint you. That was not my intention. I wanted to write about my field trial, why I think this happens quite often, what my takeaways are and that more people consider web performance as an important part of the development process besides testing.
When it comes to javascript library performance you probably need to check them in individual. Sure you shouldn't use the default import but there is much more. Byte size, benchmarks, use case, devices and so on. We could write a book about that. But if you would like to participate in a discussion we can start a collection on dev.to
Cheers
Hey just wanted to express my views. No disappointed, the blog was very informative. Since you have been working in this domain, it would be great if you can write about making performant libraries.
That is certainly an exciting topic you are right. I write that on my post bucket list!