Not Reactjs, not a framework or the servers, or API , nor the internet is the reason behind it.
Under the Hood
The story begins way back exactly one year ago. When I was covering stories on react and react native apps optimisation.
I have covered more than 15 ways in a single story on how to improve react app performance.
This is the beauty of software development it’s never stagnant or monotonous. Because today even after one year, I read a new story that tells the impact of bundle size on application performance and a mind-boggling story to understand why websites can be slow.
Right under the nose
For one year I have covered so many stories on react application optimisation but today I have got a new perspective on seeing react applications.
Bird EYE perspective — Find the root cause of problems
See it’s not rocket science but let me explain with the story -
- We first create an application in Reactjs
- Then we use Framework and packages and add code
If our senior developer requests us to improve our React app performance, we always proceed in the so-called universal direction as explained
- Check the image size
- Check the internet
- Check the API
- Check the code structure architecture or size of the repository
- Check the Javascript frameworks and language twists and turns(such as re-rendering in reactjs) and bla bla bla.
But what if I told you to follow Bottom to Top approach instead?
Let's start with the question —
How browser loads the website?
- The server sends the app bundle or response such as HTML to the browser
- Website loads HTML file and if javascript is present it will be fetched, parsed compiled and executed.
- Followed by loading of CSS
- Lastly, images are loaded or being lazy loaded
Cool, so, what really can be the reason for the entire website being slow?
Ofcourse, the things which will take time, isn't it?
So out of HTML, CSS, JS and Image if we exclude the API response here the only thing that will occupy most of the time to be executed on the browser is Javascript.
Understand that images and large-size files are not the culprits every time.
For example, the graph below tells that if the same size image and same size javascript when loads in the browser, the javascript file takes more time to process than the image.
.062 seconds for image and 2 seconds for javascript
Bottom-to-Top Approach
Check the javascript file size and try to decrease it even if the JS file includes an image try to optimise the image.
Understand the core reason how parsing, compiling and execution of the bundle can be improved significantly. That will cover up almost most of the reasons why applications are slow.
If not then it’s time to move up in the root causes list. Checking the image optimisation, re-rendering, sharding and API response things in order.
Impact of Bundle size
Most websites are now server-side and include more of the javascript code rather than HTML and CSS. Bundle when sends to the browser whether it’s compressed or decompressed will parse, compile and then execute.
Imagine if I send the browser 100Kb of app bundle whereas I send 25kb of app bundle, what do you think which one will take time?
Out of curiosity, the above npm package will help you to analyze bundle size by showing the image locally as shown below.
The smaller the bundle size the less load will be on the browser CPU, and memory and the faster it will run the website. Simple, not rocket science.
We have already suspected that javascript can be the culprit of the slowness of the app. Adding to it, if the App bundle includes most of the javascript code then more time it will take to run completely on the browser.
So we should consider the fact that our bundle size should be low at the end. As it will load the entire javascript file on the browser.
Alternative to Javascript
When I understand this I got one more question.
Then why we are supporting server-side or javascript-based applications in frontend?
Why can’t we move back to writing HTML and CSS in the front?
The answer I got is NO, it’s not correct and useful every time in every case to use mostly HTML and CSS in frontend.
Frameworks like React help develop products like Figma, Gmail, e-commerce and games much easier because of directly dealing with javascript in the front end.
Real-world example
We got a new concept called the island model. Astro is the new Multi-page application framework that deals with serving HTML files only to the browser.
But Astro can’t be used in every product it really depends on the product type and if you want to know the reason below is the story for it.
Astro can’t be used for applications where heavy states are to be managed, animations, e-commerce and dynamic websites.
Is Astro fastest framework in 2022?
In the end, we can’t develop high and bit more complex products every time easily using HTML and CSS only. We need to have javascript to make development much easier.
Not a switch, I recommend.
Improving bundle size
Let’s move back to bundle size impact.
How to improve it?
- Look for code splitting, only load the required one and try to reuse
- Minify the bundle size using loaders or webpack plugins
- Remove the unused dependencies
- Lazy load the dependencies, load only when asked
- Caching the output
Still improving bundle size will not be an easy task.
You can check the next.js bundle size using the below command.
yarn run build
It will give bundle size output and you can try making the changes and measure the bundle size improvements.
The most efficient way is to check the entire app bundle in the browser inspect tab in the performance section. You can google the way it’s not too hard to understand so not covering it much in this story.
Try introducing changes such as
- Code splitting
- Caching using React Query or Service Worker
- Minify the final output size using loaders
- You can keep measuring the bundle size locally
- Followed by checking the final performance in the inspect tab.
The performance measured by the google lighthouse will also give a percentage output of the performance.
Root cause
The root cause of the javascript and who carries the javascript is the app bundle. Why app bundle really matters is because the more it’s size more CPU power and memory it will consume more time it will take to get executed.
Understand this also, sometimes apps are fast even though the bundle size is OKAY. In that case -
- Either the CPU of the browser is really slow, it usually happens in the old devices
- Or the network connectivity is low
Nothing more than that nothing less than that.
Ultimate Plan of Action
- Which phone app is tested, if the phone is slow then check the app on the new phone.
- Make sure internet connectivity is good
- Even if the app is slow in all the phones with good internet connectivity then proceed with bundle size.
- If bundle size is not an issue check the image size, and other tantrums such as re-rendering, HTML parsing, fonts and CSS and so on.
With the bottom-to-top approach, we have a new way of addressing the entire application performance issues.
Final verdict
I am hoping to see more tools in the future helping in following this approach because nobody is talking about it.
I am able to find the root cause because I read this story written by the Engineering Manager at Google
Addy Osmani
Conclusion
I am reading more about bundle size for app performance and the root cause behind our apps being really slow.
Because I am done adding image optimisation, react rendering issues and the usual way of optimising applications. It’s time to go beyond it finding the root cause and play with it.
If you find more readings around it please do share I would love to read.
Until next time, have a good day.
Shrey
iHateReading
Top comments (24)
I agree 100% with this comment by Robin and their follow-up comments. At the risk of being combative, I think your initial premise is a bit flawed.
You have correctly identified that large bundle sizes are the cause of slow applications but not the root cause of why bundle sizes are so large in modern web applications. The reason behind large bundles is the frameworks we've turned to improve developer experience have worsened user experience.
Over the past 5 years, while we were all busy working with JS frameworks, the platform got really, really good. The best way to reduce bundle sizes is not to immediately reach for a framework but instead progressively enhance our applications with JS when needed.
Yes, the packages have evolved a lot, webpack mostly handle all the required things such as code-splitting, removing dead-code, lazy loading and so on.
Well, my initial premise have no intention to blame frameworks and langugaes behind the lagging of websites. In fact, I've mentioned them to give combat the blames react often get nowadays about being a bit slow on browser.
When I said:
I meant the web browser itself has vastly improved. To me, the best way to keep your bundle size small is not to immediately reach for a framework but instead start with HTML and CSS, only adding in JS when you absolutely need to. If you want an example, I wrote a post that starts as a React app for collecting data via a from and we strip away what isn't needed until we are left with HTML and CSS only.
blog.begin.com/posts/2022-02-09-do...
Doesn't nextjs do code splitting by default? and it lazy loads other pages when their components come into the viewport. This I believe is the benefit of MPA, you can split code up and not have to load a huge bundle all at once.
Yes, nextjs does prefetching but bundling is taken care by webpack out of the box. Sorry but nextjs is SPA and Astro is MPA the main difference is multiple entry points in MPA then in SPA.
As I have mentioned, MPA has benefits but we still can't develop high end products and state management projects like Figma using MPA or Astro. Javascript helps us to write complex applications easily.
nextjs.org/learn/foundations/how-n...
Eech page has its own bundle. I see what you mean about not being able to make high end state management projects with MPA or Astro.
Next is the best of both worlds. You can build a SPA which appears to the user to be MPA or you can build an MPA. Whatever the project you are building requires. One of the reasons I'm big on Next :)
Reduce Javascript usage to the minimun, try ROR Hotwite approach, basecamp Hey is build using it.
Not all meeds to be Javascript.
Will certainly look into it. Still reading a lot to make things practical.
The solution to a faster web is less JavaScript without a doubt.
In that line of thought Qwik way of doing it will be the future of web sites/apps development.
dev.to/builderio/qwik-the-answer-t...
Yes, Qwik can be a game changer, Qwik follows resumability concept under the hood to make it fast.
I am reading a lot nowadays about Qwik and having conversation with the author of Qwik to understand it much better.
Game change JS framework, Qwik?
Yes, agree, considering your points in the discussion. We have a addon to the approach of how websites can be optimised.
I believe and reading how to go for a best approach for optimising the websites covering each and every aspects of web development.
Sorry, I didn't understand it quite well. But if suggesting a way then Yes bundling is a most proper and optimised way in 2022 because it's compressed and served fast over internet. In addition, bundle itself can support lazy loading and other features to optimise it.
Great article, keep the good work! Liked and followed! 🚀
Thanks for reading and I will try my best every time.
Great post. Everything is perfectly explained
Really site speed matters for search engine and for user experience also . Thank mates for sharing this over here. ~ Jozef behr
Astro with their (react, vue, svelte, tailwind) integrations is worth looking at.🤔