DEV Community

Tirth Bodawala
Tirth Bodawala

Posted on

When to use hydrateRoot for best UX and Core-Web-Vitals?

Hi Everyone,
I have a question regarding server-side rendering in React using the renderToPipeableStream method from react-dom/server. I am unsure about the best practice for hydrating the application on the client side to achieve optimal Core Web Vitals scores and user experience.

Here are some points to consider:

  • Our app uses Suspended components with React.Suspense and React.lazy, and we also use React for loading data in suspended mode.
  • We use a bundler like webpack/esbuild to generate the output files server.ts and /js/client.mjs. The paths in the example below are for explanation purposes only and may not be accurate.

Question:

My specific question is: should we hydrate the application only after the page fully rendered with all suspended components rendered, or should we hydrate it as soon as the client script file is loaded?

Here's a sample of our server.ts code:

import App from './app';
import { renderToPipeableStream } from 'react-dom/server';

// ... 

renderToPiepableStream(<App />, {
  bootstrapModules: ['/js/client.mjs']
  // ... other code
  // onShellReady() {
  //  response.setHeader('content-type', 'text/html');
  //  pipe(response);
  // }
});

Enter fullscreen mode Exit fullscreen mode

And here's a sample of our /js/client.mjs code:



const render = async () => {
  // Code splitting for react-dom/client
  const { hydrateRoot } = (() => import('./react-dom-client-xsd21.mjs'))();
  // Code splitting for ./app
  const { App } = (() => import('./app-hash2121.mjs'))();
  hydrateRoot(
    document.getElementById('root'),
    <App />
  );
};

if (document.readyState === 'complete') {
  render();
} else {
  addEventListener("readystatechange", (event) => {
     if (document.readyState === 'complete') {
       render();
     }
  }, { passive: true });
}

Enter fullscreen mode Exit fullscreen mode

Some additional questions I have include:

  • Should I lazy load React and react-dom/client?
  • Should I lazy load the App component?
  • Should I wait for the page to fully load before hydrating, or can I start hydrating when the document.readyState is interactive?

I appreciate any assistance, and apologize in advance for any code typos or poor implementation examples.

EDITED:
Follow-up question:

Does partial hydration help with improvements in core-web-vitals?

I was going through the blog and saw the concept of Partial Hydration, Which Gatsby also utilizes and I think might be the base for Server Components as well.
Please correct me if I am wrong.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

AWS Security LIVE!

Hosted by security experts, AWS Security LIVE! showcases AWS Partners tackling real-world security challenges. Join live and get your security questions answered.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️