Boost Your React App's Performance with Lazy Loading, Hydration, and Code Splitting
After a React/Next.js sabbatical, I am back to building ways!! At the time of writing, I am working on an admin dashboard for an online marketplace application powered by Next.js and Typescript. As is the case with every project I undertake, learning new things or getting a refresher on things I have learned in the past is inherent. In this article, I will be writing about some cool React features and concepts that every React and Next.js developer will be better off if they learn how they work and how to use them in their own projects (well that's my opinion on the issue so don't quote me on that)
As an outline of what's to come, the features we will be talking about are: Lazy loading, Code Splitting and Hydration. Into the "Reactverse" we go!!
Lazy Loading
Lazy loading is definitely not a new feature around the block. It's been around for quite some time. However, it is remains a feature with sufficient potential to boost the performance of your React applications. Lazy loading defers the loading of a React component's code to when it is first needed i.e. to when it is rendered for the first time. To make use of this feature you have to import it from the React library. Let's see how it is used with some code examples.
import { lazy } from "react";
const LazyLoadedComponent = lazy(() => import('./LazyLoaded.tsx'));
In the code above, we imported the lazy
module from the React library. To make a component to be lazy loaded, you import it within a function called load
passed as a parameter to lazy
. load
returns a Promise and it is not called until you try to render the returned component i.e. the one imported within the load
function. When the component is rendered, the results are cached so that React won't have to called load
more than once. As a side note, to be able to import the component within the load
function as we did in the the code snippet above, it has to have been exported as the default export.
To make sure your lazy loaded component doesn't get resetted unexpectedly, make sure you don't declare them inside other components. You should rather always declare them at the top level of your module.
React recently added the <Suspense>
component to the library, allowing you to display some fallback content (for example a loader) while components nested within it are still loading. I was so relieved when I learned about this cause I no longer have to leverage the useState
hook to check if a component is still loading or not. Below is a code example of how you'd typical use <Suspense>
<Suspense fallback={<Loading />}>
<h2>Hello World, Welcome</h2>
<LazyLoadedComponent />
</Suspense>
So while the <LazyLoadedComponent />
is being loaded, <Loading />
will be displayed as a fallback.
Code Splitting
The name chosen for this feature is self explanatory. With code splitting, React breaks down your application into smaller chunks. Doing this can greatly reduce the initial JavaScript bundle size the browser has to download. This can lead to faster initial page loads as these chunks of code are only loaded on demand based on user interaction or routing.
Code Splitting is performed when your application is being bundled by tools such as Webpack, Rollup and others. You can use dynamic imports within your React application to indicate pieces of code that you want splitted into smaller chunks. Build tools then use their code splitting functionality to analyze your code and generate different JavaScript bundles.
If you feel the need for more fine-grained control you can use code splitting libraries like react-loadable
which is deemed easy to use by many.
Hydration
Hydration is another feature that I came to learn more about in the project I am currently working on. In this project, I created a digital clock component and made sure I avoided the errors that came with changing state directly within the set state function, mutating the state object and other common errors that come up when you use useState
. After having done this, I kept getting a text mismatch error about the HTML that the server rendered and what is rendered on the client as the clock was updating every other second.
When I did some research on solving this issue, I learned about hydration. The question on you mind right now is probably what is hydration all about. Let's talk about that real quick. I don't think I can phrase it better than what I read in the React documentation so here you go.
In React, “hydration” is how React “attaches” to existing HTML that was already rendered by React in a server environment. During hydration, React will attempt to attach event listeners to the existing markup and take over rendering the app on the client.
So it is fundamentally a process in which React transforms content pre-rendered on the server into an interactive user interface. There are so many benefits that hydration has to offer. For instance; It can greatly improve the time your web application takes to become interactive to the end user and even boost your application's SEO.
As I hinted above, hydration can sometimes constitute a few issues. An example of an issue you might face is that during rehydration, in a process called reconciliation, the content pre-rendered by the server is compared with what is rendered on the client-side. If the content differs, you can get a text mismatch error. This kind of error is very common when you are displaying a timestamp. Thank goodness that to every problem, there is a solution. To get rid of the error, you can set the suppressHydrationWarning
attribute on the element for which you want to silence hydration to true
.
Conclusion
When building an application using a framework like React or other JavaScript frameworks, the way you implement the features in your application can influence performance either positively or negatively. With the features we have just examined, you have more tools under your belt to take the performance of your application to the next level. As we have just seen, these features can: improve the initial load time of your application, improve how the application performs on search engines amongst other benefits. Don't sit on the knowledge gained here. Use it to boost the performance of your React and Next.js applications. Good luck and working towards making the world a better place with the code that you write.
Subscribe to my newsletter
Read articles from Brandon Damue directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Brandon Damue
Brandon Damue
👋 Hello, I'm Brandon Damue, a 🚀 software developer and ✍️ technical writer with a passion for 📚 reading, 🔧 self-improvement, and a keen interest in various ☁️ cloud computing technologies. I have years of experience in software development, and I've honed my skills in multiple programming languages and frameworks, as well as ☁️ cloud computing technologies such as AWS. My expertise allows me to build and deploy robust and scalable applications as well write articles to help developers in their careers and learning journeys. As a 📝 technical writer, I have a talent for explaining complex concepts in a clear and concise manner. I've published numerous articles and tutorials on various platforms, and I'm well-known for my ability to provide valuable insights and knowledge. On my Hashnode blog, I share my insights and experiences on software development, technology, and personal growth. Follow my blog to stay up-to-date on the latest trends and advancements in ☁️ cloud computing and the tech industry. 💡