Server vs Client
- Server Components: These are rendered on the server but can utilize hooks like useState to retain interactivity. Think of them as a bridge between SSR and CSR, offering the best of both worlds.
- Client Components: Nested within Server Components, these are rendered on the client, allowing you to build highly interactive UI elements within an overall server-rendered application.
- Data Fetching Strategies: Choose between getStaticProps for one-time static data fetching and getServerSideProps for dynamic data on each request, tailoring your approach to individual components.
Use-client: Unleashing the Power of the Client
Imagine components that spring to life instantly in the user's browser, responding to interactions with lightning speed. use-client takes charge of just that, making it the ideal choice for:
- Components without initial server-side data fetching: If your component doesn't rely on data pulled from the server to display its content, use-client keeps things quick and smooth by rendering it directly in the browser.
- Highly interactive elements: Dynamic components like dropdowns, sliders, and real-time chat functionality shine with use-client, as their responsiveness benefits from the direct browser-to-component communication.
- Performance-hungry scenarios: Applications where every millisecond counts, e.g., single-page applications (SPAs) and e-commerce platforms, can leverage use-client to ensure a seamless and lag-free user experience.
Use-server: Mastering the Art of SEO and Pre-Rendering
Think of use-server as the SEO champion, ensuring your application is readily discovered by search engines and delivers a fully formed experience from the get-go. It excels in situations where:
- SEO is a top priority: Search engines love to see fully rendered HTML content, and use-server guarantees that your pages are SEO-ready, boosting your discoverability in search results.
- Initial data fetching is crucial: Need dynamic content like news feeds or personalized recommendations to be available instantly? use-server fetches the data on the server before sending the page to the client, leading to a smooth and immediate user experience.
- Content freshness matters: For applications with frequently updated content, use-server ensures that every user receives the latest and most relevant information.
server-only
is to poison a module, so that if a client module, imports from it, the application crashes. An error is raised.
use server
is used to mark code as executable server side:
Request-Response Lifecycle
Broadly speaking, all websites follow the same Request-Response Lifecycle:
- User Action: The user interacts with a web application. This could be clicking a link, submitting a form, or typing a URL directly into the browser's address bar.
- HTTP Request: The client sends an HTTP request to the server that contains necessary information about what resources are being requested, what method is being used (e.g.
GET
,POST
), and additional data if necessary. - Server: The server processes the request and responds with the appropriate resources. This process may take a couple of steps like routing, fetching data, etc.
- HTTP Response: After processing the request, the server sends an HTTP response back to the client. This response contains a status code (which tells the client whether the request was successful or not) and requested resources (e.g. HTML, CSS, JavaScript, static assets, etc).
- Client: The client parses the resources to render the user interface.
- User Action: Once the user interface is rendered, the user can interact with it, and the whole process starts again.
A major part of building a hybrid web application is deciding how to split the work in the lifecycle, and where to place the Network Boundary.
Network Boundary
In web development, the Network Boundary is a conceptual line that separates the different environments. For example, the client and the server, or the server and the data store.
In React, you choose where to place the client-server network boundary wherever it makes the most sense.
Behind the scenes, the work is split into two parts: the client module graph and the server module graph. The server module graph contains all the components that are rendered on the server, and the client module graph contains all components that are rendered on the client.
It may be helpful to think about module graphs as a visual representation of how files in your application depend on each other.
You can use the React "use client"
convention to define the boundary. There's also a "use server"
convention, which tells React to do some computational work on the server.