![]() |
VOOZH | about |
We’re so glad you’re here. You can expect all the best TNS content to arrive Monday through Friday to keep you on top of the news and at the top of your game.
Check your inbox for a confirmation email where you can adjust your preferences and even join additional groups.
Follow TNS on your favorite social media networks.
Become a TNS follower on LinkedIn.
Check out the latest featured and trending stories while you wait for your first TNS newsletter.
In web development, Hydration is a technique to add interactivity to server-rendered HTML. It’s a technique in which client-side JavaScript converts a static HTML web page into a dynamic web page by attaching event handlers to the HTML elements.
However, attaching event handlers to the Document Object Model (DOM) is not the most challenging or expensive part of hydration.
In this article, I’ll explain why I believe hydration is overhead. It’s not the solution; it’s a hack that consumes memory and slows down startup, especially on mobile. For the sake of this article, let’s define overhead as work that can be avoided and still leads to the same end result.
The hard part of hydration is knowing what event handlers we need and where they need to be attached.
The added complication is that WHAT is a closure that closes over APP_STATE and FW_STATE:
So how do we recover WHAT and WHERE? By downloading and executing the rendered components in HTML. This is the expensive part.
In other words, hydration is a hack to recover the APP_STATE and FW_STATE by eagerly executing the app code in the browser and involves:
Let’s call the first three steps the Recovery phase.
Recovery is when the framework is trying to rebuild the application. The rebuild is expensive because it requires downloading and executing the application code.
Recovery is directly proportional to the complexity of the page being hydrated and can easily take 10 seconds on a mobile device. Since Recovery is the expensive part, most applications have a suboptimal startup performance, especially on mobile.
Recovery is also overhead: It rebuilds information that the server already gathered as part of server-side rendering (SSR) or static site generation (SSG). Instead of sending the information to the client, the information was discarded. As a result, the client must perform expensive Recovery to rebuild what the server already had. If only the server had serialized the information and sent it to the client along with HTML, the Recovery could have been avoided. The serialized information would save the client from eagerly downloading and executing all of the components in the HTML.
In other words, the re-execution of code on the client that the server already executed as part of SSR/SSG is what makes hydration pure overhead.
To remove overhead, the framework must not only avoid Recovery, but also step four from above: attaching the WHAT to WHERE.
To avoid this cost, you need three things:
The above setup is resumable because it can resume the execution where the server left off without redoing any work that the server already did. By creating the WHAT lazily as a response to a user event, we can avoid doing all the unnecessary work that happens in hydration. All this means no overhead.
The DOM elements retain the event handlers for the lifetime of the element. Hydration eagerly creates all of the listeners, so it needs memory to be allocated on startup.
On the other hand, resumable frameworks do not create the event handlers until after the event is triggered. Therefore, they will consume less memory than hydration. Furthermore, the event handler is released after its execution, returning the memory.
In a way, releasing the memory is the opposite of hydration. It is as if the framework lazily hydrates a specific WHAT, executes it and then dehydrates it. There is not much of a difference between the first and nth execution of the handler.
To put this idea into practice, we built Qwik, a framework that is designed around “resumability” and achieves a speedy startup. To show you the impact of resumability, we built a to-do app demo that runs on Cloudflare edge. This page is ready for interaction in about 50 ms.
We also used the resumable strategy (and Qwik) to redo our website, builder.io. Using Qwik (and our other solution, Partytown), we were able to cut down 99% of the JavaScript in our site and get a PageSpeed score of 100/100. (You can still visit the old page using hydration to compare and experience the performance difference for yourself.)
Put simply, hydration is overhead because it duplicates work. The server builds up the WHERE and WHAT (APP_STATE and FW_STATE), but the information is discarded instead of being serialized for the client. The client then receives HTML that does not have sufficient information to rebuild the application. The lack of information forces the client to eagerly download the application and execute it to recover the WHERE and WHAT.
An alternative approach is resumability. Resumability focuses on transferring all of the information (the WHERE and WHAT) from the server to the client. Only a user interaction forces the client to download code to handle that specific interaction. The client is not duplicating any work from the server; therefore, there is no overhead.