Explorando los fundamentos de los Componentes del Servidor React

Rate this content
Bookmark

He estado desarrollando un marco minimalista para los Componentes del Servidor React (RSC). Esta charla compartirá mi viaje para entender profundamente RSC desde una perspectiva técnica. Demostraré cómo operan las características de RSC a un nivel bajo y proporcionaré ideas sobre lo que RSC ofrece en su núcleo. Al final, deberías tener un modelo mental más fuerte de los fundamentos de los Componentes del Servidor React.

21 min
12 Dec, 2023

Comments

Sign in or register to post your comment.

AI Generated Video Summary

Esta charla presenta los Componentes del Servidor React (RSC) y explora su proceso de serialización. Compara RSC con la representación tradicional del lado del servidor (SSR) y explica cómo RSC maneja las promesas e integra los componentes del cliente. La charla también discute el manifiesto de RSC y el proceso de deserialización. Luego, el orador presenta el marco Waku, que soporta la agrupación, el servidor, el enrutamiento y SSR. Los planes futuros para Waku incluyen la integración con las bibliotecas de gestión del estado del cliente.

1. Introducción a los Componentes del Servidor React

Short description:

¡Hola a todos! Estoy muy emocionado de dar una charla este año sobre los componentes del servidor React. Compartiré lo que he aprendido hasta ahora, exploraré los fundamentos de RSC y hablaré de mi proyecto, Waku. RSC significa Componente del Servidor React, y se trata de usar React en lugares diferentes al navegador. El núcleo de RSC es la serialización, que permite que React funcione en espacios de memoria separados. Procedamos con la demostración utilizando el canal canario de React y el paquete React-ServerDOM-webpack.

¡Hola a todos! Estoy muy emocionado de dar una charla este año, especialmente porque es sobre mi nuevo proyecto. Se trata de los React Server components, con los que he estado aprendiendo y experimentando durante varios meses. Hoy, voy a compartir lo que he aprendido hasta ahora. Mi nombre es Daishi Kato. Soy un desarrollador de código abierto, y algunos de mis proyectos populares son Jotai y Zustand. Tal vez lo sepan, pero ambos son para la gestión de estado. Son como competidores, pero en realidad es bueno porque nos aportan más feedback. Actualmente, Zustand está adelante y Jotai está persiguiéndolo. En el React Day Berlin 2022, hablé sobre Jotai. Es un honor estar aquí hablando de nuevo este año.

En la primera parte de esta charla, exploraremos los fundamentos de RSC. Tengo una demostración usando solo Node.js sin ningún framework. No es una codificación en vivo, pero espero que lo encuentren disfrutable. Si están interesados, pueden probarlo por su cuenta más tarde. Esta demostración es principalmente para los autores de bibliotecas o aquellos que quieren entender los comportamientos internos de RSC.

En la segunda parte hablaremos de mi proyecto, Waku. Es un framework de React centrado en RSC. Permítanme comenzar con una respuesta mía. ¿Qué es RSC? RSC significa Componente del Servidor React. Sin embargo, la parte del servidor en el nombre puede ser confusa. Se trata más de usar React en lugares diferentes a, digamos, el navegador. Y solo una nota rápida, técnicamente también puedes usar RSC en los navegadores. Profundizando, ¿cuál es el núcleo de RSC? Creo que la esencia es la serialización. Antes de RSC, React trabajaba dentro de un solo espacio de memoria. Pero con RSC, React ahora puede trabajar en espacios de memoria separados. Esto podría ser entre un servidor y un cliente, dos servidores o incluso dentro de los hilos de trabajo del navegador. Ahora, procedamos con la demostración. Comencemos configurando un proyecto de prueba. Por ahora, usaremos el canal canario de React hasta que salga una versión estable. El paquete React-ServerDOM-webpack está aquí para darnos las características de RSC.

2. Introducción a RSC y SSR

Short description:

Comenzaremos con un ejemplo simple sin RSC. Es React tradicional, y no tiene nada que ver con RSC. Este elemento JSX no es serializable. Veamos el renderizado del lado del servidor tradicional con nuestro próximo ejemplo. El renderizado del lado del servidor o SSR es un proceso para generar contenido HTML en el servidor. Técnicamente, SSR también puede ejecutarse en navegadores. Ahora, examinemos el código. Utilizamos la función RenderToPipeableStream de react-dom-server. Esta función está disponible en la versión estable del paquete react-dom. Al ejecutar este código, se mostrará el HTML resultante. En nuestro próximo ejemplo, veremos cómo funciona RSC en comparación con este ejemplo de SSR. Vamos a explorar cómo se desempeña el aspecto de serialización de RSC. En esta demostración, utilizamos la función renderToPipableString() de react-server.webpack/.server.

Está diseñado específicamente para webpack porque algunas de sus características tienen una relación cercana con los empaquetadores. Sin embargo, no usamos webpack en nuestra demostración de todos modos.

Ahora sigamos adelante. Comenzaremos con un ejemplo simple sin RSC. Aquí está nuestro primer ejemplo. Es React tradicional, y no tiene nada que ver con RSC. Al mirar el código, encontrarás que simplemente estamos definiendo un AppComponent y mostrando el resultado con console.log. Cuando ejecutas el código, mostrará un objeto JSON. A esto se le suele referir como un elemento React o un elemento JSX. Lo importante a tener en cuenta aquí es que este elemento JSX no es serializable. Por ejemplo, contiene un símbolo para su propiedad de tipo especial. En este ejemplo, la propiedad type es una función que no es serializable. Exploraremos cómo RSC aborda esto en breve, pero antes de eso, veamos el renderizado del lado del servidor tradicional con nuestro próximo ejemplo.

El renderizado del lado del servidor o SSR es un proceso para generar contenido HTML en el servidor. Es importante tener en cuenta que SSR es diferente de RSC. Aunque RSC puede ejecutarse en el servidor, no produce HTML. Por cierto, SSR técnicamente también puede ejecutarse en navegadores. Ahora, examinemos el código. Utilizamos la función RenderToPipeableStream de react-dom-server. Esta función está disponible en la versión estable del paquete react-dom. Dado que RenderToPipeableStream devuelve un stream, no podemos simplemente usar console.log. En su lugar, lo dirigimos a Process.standard.out. Al ejecutar este código, se mostrará el HTML resultante. SSR se utiliza comúnmente durante la carga inicial de la página para mejorar la user experience y la optimization del motor de búsqueda. En nuestro próximo ejemplo, veremos cómo funciona RSC en comparación con este ejemplo de SSR.

Ahora, exploremos cómo se desempeña el aspecto de serialización de RSC. En esta demostración, utilizamos la función renderToPipableString() de react-server.webpack/.server. Tenga en cuenta, esto está disponible solo en la versión Canary. Excepto por importar la función de un paquete diferente, el resto permanece igual que en el ejemplo anterior. Al ejecutar este código, obtenemos una salida similar a JSON.

3. Carga útil de RSC y Deserialización

Short description:

RSC es independiente del renderizador y puede manejar cualquier valor de JavaScript. Serializa los elementos JSX y transfiere sus streams para su deserialización en otro lugar. La carga útil de RSC es una cadena que permite la transferencia de datos paso a paso.

A esto se le conoce comúnmente como la carga útil de RSC. Esta carga útil es una representación interna y a menudo se considera como un detalle de implementación. RSC es independiente del renderizador, lo que significa que, aunque se use con frecuencia con react-dom, RSC no está estrictamente vinculado al DOM.

Además, como puedes ver en este ejemplo, proporcionamos una opción a nulljs, react-server-condition. Es esencial porque sin esto, el código no se ejecuta. Esta especificación es para determinar si el código se ejecuta bajo un entorno RSC. A continuación, veremos cómo se lleva a cabo el proceso de deserialización. En esta demostración, nos estamos centrando en la deserialización. Veamos el código. El react-server.webpack slash client se refiere al lado del cliente de la biblioteca. Normalmente se usa en navegadores, pero para esta demostración, estamos usando la versión de node.js. La función createFromNodeStream es para deserializar la carga útil de RSC. Para hacer que la demo funcione en una sola instancia de Node.js, estamos usando el stream de paso. En escenarios del mundo real, los datos de este stream podrían enviarse a través de una red.

El resultado en la consola puede parecer familiar. Es lo mismo que el elemento JSX que discutimos en nuestro primer ejemplo. De hecho, ejecutar la declaración console.log que está comentada al final del código mostrará el mismo resultado dos veces. Esta es la funcionalidad principal de RSC. Serializar un elemento JSX, transferir su stream por cualquier método y luego deserializarlo para reproducir el mismo resultado en otro lugar. Profundizaremos un poco más en los próximos ejemplos.

La capacidad de RSC para serializar datos no es solo para React. En realidad, puede manejar cualquier valor de JavaScript. Yo lo veo de esta manera. RSC soporta elementos JSX además de los valores estándar de JavaScript. Ahora, echando un vistazo al código y su salida, este ejemplo básico demuestra que RSC puede manejar objetos, arrays, cadenas y números. Aunque estamos destacando la serialización en este ejemplo, la deserialización funcionaría de manera similar. A primera vista, esto puede parecer muy básico. Algo que podemos hacer con el archivo de cadena JSON y las partes JSON. Entonces, ¿cuál sería el aspecto único de RSC? Podrías notar un prefijo extra antes de la cadena JSON, que en este caso es cero columna. Recuerda, la carga útil de RSC está diseñada como una cadena lo que significa que los datos se transfieren paso a paso.

4. Promesas RSC y Componentes del Cliente

Short description:

En esta sección, exploramos cómo RSC maneja las promesas y cómo es similar a React Suspense. También discutimos la integración de los Componentes del Cliente con los Componentes del Servidor y el proceso de serialización para los Componentes del Cliente.

Cada línea representa un fragmento de JSON con el prefijo actuando como un ID para que pueda vincularse a otro fragmento de JSON. En el siguiente ejemplo, veremos cómo se transfiere data con el tiempo. Este ejemplo muestra cómo RSC maneja las promesas. Normalmente, las promesas pueden ser serializadas. Pero RSC lo hace posible enviando el valor resuelto en un stream a medida que pasa el tiempo. En el otro extremo, al deserializar, obtienes lo que parecía ser la promesa original. Mirando el código, la función simplemente devuelve un array que contiene una nueva promesa. Si ejecutas este código, primero mostrará un array con un marcador de posición dentro. Espera un segundo, y aparece el valor resuelto. Y no tienes que preocuparte por cómo fue enviado. Simplemente funciona detrás de la escena.

Este ejemplo es sobre una promesa básica. Hasta donde entiendo, esto debería ser similar a cómo funciona React Suspense. Si usas suspense en el servidor, el servidor primero envía un fallback y un marcador de posición, que se resolverá después. En la siguiente diapositiva, ajustaremos ligeramente nuestro enfoque y veremos cómo funcionan los Componentes del Cliente con RSC. Una de las características más grandes con RSC son los Componentes del Cliente. RSC nos permite entrelazar los Componentes del Cliente con los Componentes del Servidor. Ahora, vamos a revelar cómo funciona la Serialización para los Componentes del Cliente. Echando un vistazo al código, hay un Componente Contador, que es un Componente del Cliente. A continuación, inspecciona el archivo Counter.js. En la parte superior, notarás el uso de useClientDirective. Esto es crucial, ya que indica que el archivo actúa como un punto de entrada para los Componentes del Cliente. Solo necesitamos la directiva para el punto de entrada. No necesitamos poner useClientDirectives para todos los archivos. La parte restante del archivo simplemente define un Componente React regular. De vuelta en nuestro archivo principal, hay una mención de ReactServer.webpack.node.register. Esta declaración registra un manejador para el useClientDirective. Aunque React ofrece múltiples métodos, hemos elegido este método en particular por su simplicidad en nuestra demostración. Para poner en marcha nuestra demo, se requiere un pequeño ajuste.

5. Manifiesto RSC y Deserialización

Short description:

Normalmente, esto sería producido automáticamente por un paquete. Pero para nuestra demostración, lo hemos definido manualmente. Este objeto de manifiesto se pasa a la función renderToPipelineString. Al ejecutar el código se muestra un resultado críptico. A continuación, echemos un vistazo breve a cómo funciona el aspecto de deserialización. En esta demo, estamos ampliando el ejemplo anterior añadiendo el proceso de deserialización. El resultado muestra un elemento div con dos hijos. El primero es un elemento h1, y el segundo es un elemento lazy, que representa nuestro componente del cliente. Este es el final de nuestra demo, pasemos al siguiente tema. Hemos aprendido cómo funciona RST, especialmente su proceso de serialización. Ahora podrías preguntarte si podemos usar directamente esas funciones en el desarrollo de nuestra aplicación. Se hace evidente que algo como un marco sería útil. Mi motivación era entender mejor RST e integrar algunas de mis bibliotecas. Y eso me llevó a crear un marco mínimo que apoya principalmente a RST.

Encontrarás un objeto de manifiesto en nuestro código. Normalmente, esto sería producido automáticamente por un paquete. Pero para nuestra demostración, lo hemos definido manualmente. Este objeto de manifiesto se pasa a la función renderToPipelineString. Al ejecutar el código se muestra un resultado críptico. Aunque no necesitas entender cada detalle, vale la pena notar la línea que muestra los fragmentos de ID y más. Son algo que detallamos en el objeto de manifiesto. Esta información se vuelve clave al deserializar la carga de RST en el cliente, y permite cargar dinámicamente el código del componente del cliente. Tal información se llama una referencia del cliente.

A continuación, echemos un vistazo breve a cómo funciona el aspecto de deserialización. En esta demo, estamos ampliando el ejemplo anterior añadiendo el proceso de deserialización. Las áreas marcadas con rectángulos rojos indican las diferencias con el ejemplo anterior. Como en una de las demos anteriores, utilizamos CreateFromNodeStream y Passthrough. El id dentro del objeto de manifiesto es el nombre del archivo en este caso, para que el cliente pueda importarlo desde el servidor más tarde. Además, hemos creado un objeto de configuración, que pasaremos a la función CreateFromNodeStream. Considera este enfoque una solución temporal. No representa la implementación real. Ahora veamos el resultado. El resultado muestra un elemento div con dos hijos. El primero es un elemento h1, y el segundo es un elemento lazy, que representa nuestro componente del cliente. Esto demuestra el árbol de React donde los componentes del servidor y del cliente están entrelazados. Teóricamente, si renderizamos este árbol, mostrará el contenido. No lo haremos en esta charla, pero será un desafío interesante.

Este es el final de nuestra demo, pasemos al siguiente tema. Hemos aprendido cómo funciona RST, especialmente su proceso de serialización. En nuestra demo, simplemente usamos funciones exportadas por las bibliotecas de React. Ahora podrías preguntarte si podemos usar directamente esas funciones en el desarrollo de nuestra aplicación. Sería bastante difícil y podría requerir mucho esfuerzo. Se hace evidente que algo como un marco sería útil. Mi motivación era entender mejor RST e integrar algunas de mis bibliotecas. Y eso me llevó a crear un marco mínimo que apoya principalmente a RST.

6. Características del marco WACU

Short description:

El marco en el que he estado trabajando se llama WACU. Admite cuatro características: empaquetador, servidor, enrutador y SSR. Se requiere un empaquetador para admitir directivas y resolver referencias del cliente. Un servidor es necesario para datos dinámicos, pero no para datos estáticos. Un enrutador puede mejorar el rendimiento al permitir que el servidor realice tareas antes de enviar datos al cliente. SSR es una característica clave en un marco de React.

El marco en el que he estado trabajando se llama WACU. No podemos entrar demasiado en detalles, pero permíteme contar brevemente qué características se están desarrollando. Entonces, ¿qué falta en el aspecto central de RST? En otras palabras, ¿qué se requiere más allá de la serialización? Discutiremos cuatro características ya que actualmente son compatibles con mi marco.

La primera característica es un bundler. Recuerda una de nuestras masterclass con la directiva use client. Aunque usamos la función de una de las bibliotecas de React, básicamente es trabajo de un bundler. Técnicamente podríamos crear una referencia del cliente utilizando una solución runtime, pero tal enfoque podría no ser ideal y podría afectar negativamente la developer experience. Por lo tanto, un bundler es esencial para admitir esas directivas. Junto con un bundler, las bibliotecas de React ayudan a manejarlas. Un bundler también es crucial para resolver una referencia del cliente para obtener el módulo del cliente. Creo que es justo concluir que se requiere un bundler para RSC.

La segunda característica es un servidor. La serialización de RSC resulta en un flujo. Para transmitir este flujo a través de una red, requerimos un servidor capaz de RSC, generalmente un servidor HTTP. Este servidor debe estar equipado para manejar solicitudes específicas y responder con cargas útiles de RSC. Un servidor es esencial para producir data dinámica. Sin embargo, cuando se trata de data estática, el servidor capaz de RSC no es estrictamente necesario. Esto se debe a que podemos construir cargas útiles de RSC en tiempo de construcción y luego implementarlas con un servidor HTTP estándar. Por lo tanto, RSC no siempre necesita un servidor. Para diferenciar los dos escenarios, podríamos referirnos a ellos como RSC dinámico, que involucra un servidor, y RSC estático, que no lo hace.

La tercera característica es un enrutador. Si bien la necesidad de un bundler y un servidor es sencilla, entender la importancia del enrutador para RSC puede ser menos obvio. Por favor, no lo entiendas mal, pero un enrutador no es estrictamente necesario, en mi opinión. Sin embargo, si tu aplicación utiliza un enrutador, podría ser de ayuda. Esto se debe a que un enrutador permite que el servidor conozca más detalles antes de que comience el cliente. Esto significa que el servidor puede hacer tareas antes de enviar data al cliente, y puede llevar a un mejor performance. Consideramos un enrutador como una característica adicional para un marco de RSC. Sin embargo, con un enrutador, podemos optimizar aún más el uso de RSC.

La última característica es SSR. SSR es típicamente una característica clave en un marco de React.

7. SSR y Planes Futuros

Short description:

SSR no es necesario para un marco de RSC, pero mejora la carga inicial de la página. Los sitios estáticos pueden necesitar solo un empaquetador, mientras que los sitios dinámicos requieren un servidor. Para aplicaciones complejas, añade un enrutador y SSR. Los planes futuros incluyen la integración con bibliotecas de gestión de estado del cliente. Waku es un proyecto de código abierto en curso. Visita el repositorio de Waku en GitHub para obtener más detalles.

En nuestro contexto, SSR se refiere a generar HTML en servidores. Entonces, SSR en sí mismo no está relacionado con RSC, lo que implica que SSR no es necesario para un marco de RSC. Sin embargo, hay un beneficio de SSR, y eso es mejorar la carga inicial de la página. Recuerda que no contribuye a la performance para actualizaciones posteriores. Entonces, si la carga inicial de la página performance es una prioridad para tu aplicación, entonces SSR es esencial. Si la página inicial es contenido puramente estático, puedes generar el HTML durante el tiempo de construcción, también conocido como SSG. Los distinguimos como SSR Dinámico y SSR Estático.

He estado desarrollando Waku desde el pasado mayo. Incluye las cuatro características que acabo de presentar. Notablemente, estas cuatro características están apiladas, lo que te permite usarlas selectivamente. Para sitios estáticos, es posible que solo necesites un bundler. Para sitios dinámicos, sería apropiado introducir un servidor. Para aplicaciones más complejas, considera agregar un enrutador y SSR.

Mirando hacia el futuro, uno de mis objetivos es desarrollar una solución integrada con bibliotecas de state management del cliente, como Jotai y Zastand. Anticipo la necesidad de un enrutador dedicado para estas integraciones. Seguiremos explorando esta dirección. Waku es un proyecto en curso y si te interesa, es de open-source, tu contribución sería invaluable. No dudes en visitar el repositorio de Waku en GitHub para ver la implementación de estas características. Siempre es bienvenida tu retroalimentación. Y con eso he llegado al final de mi charla. Gracias por tu atención. Espero que hayas obtenido algo valioso de esta charla.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2023React Advanced Conference 2023
27 min
Simplifying Server Components
Server Components are arguably the biggest change to React since its initial release but many of us in the community have struggled to get a handle on them. In this talk we'll try to break down the different moving parts so that you have a good understanding of what's going on under the hood, and explore the line between React and the frameworks that are built upon it.
React Summit 2023React Summit 2023
26 min
Server Components: The Epic Tale of Rendering UX
Server components, introduced in React v18 end these shortcomings, enabling rendering React components fully on the server, into an intermediate abstraction format without needing to add to the JavaScript bundle. This talk aims to cover the following points:1. A fun story of how we needed CSR and how SSR started to take its place2. What are server components and what benefits did they bring like 0 javascript bundle size3. Demo of a simple app using client-side rendering, SSR, and server components and analyzing the performance gains and understanding when to use what4. My take on how rendering UI will change with this approach
React Advanced Conference 2023React Advanced Conference 2023
28 min
A Practical Guide for Migrating to Server Components
Server Components are the hot new thing, but so far much of the discourse around them has been abstract. Let's change that. This talk will focus on the practical side of things, providing a roadmap to navigate the migration journey. Starting from an app using the older Next.js pages router and React Query, we’ll break this journey down into a set of actionable, incremental steps, stopping only when we have something shippable that’s clearly superior to what we began with. We’ll also discuss next steps and strategies for gradually embracing more aspects of this transformative paradigm.
React Day Berlin 2023React Day Berlin 2023
27 min
React Server Components
React Server Components are a newer way of working with React that is widely adopted in frameworks like Next.js. In this talk, we will look under the surface of how they work and are executed on the server side, and how they fit with server rendering and traditional React apps.

Workshops on related topic

React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
WorkshopFree
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
React Advanced Conference 2023React Advanced Conference 2023
153 min
React Server Components Unleashed: A Deep Dive into Next-Gen Web Development
Workshop
Get ready to supercharge your web development skills with React Server Components! In this immersive, 3-hour workshop, we'll unlock the full potential of this revolutionary technology and explore how it's transforming the way developers build lightning-fast, efficient web applications.
Join us as we delve into the exciting world of React Server Components, which seamlessly blend server-side rendering with client-side interactivity for unparalleled performance and user experience. You'll gain hands-on experience through practical exercises, real-world examples, and expert guidance on how to harness the power of Server Components in your own projects.
Throughout the workshop, we'll cover essential topics, including:
- Understanding the differences between Server and Client Components- Implementing Server Components to optimize data fetching and reduce JavaScript bundle size- Integrating Server and Client Components for a seamless user experience- Strategies for effectively passing data between components and managing state- Tips and best practices for maximizing the performance benefits of React Server Components
Workshop level: 
No matter your current level of React expertise, this workshop will equip you with the knowledge and tools to take your web development game to new heights. Don't miss this opportunity to stay ahead of the curve and master the cutting-edge technology that's changing the face of web development. Sign up now and unleash the full power of React Server Components!
React Advanced Conference 2021React Advanced Conference 2021
170 min
Build a Custom Storefront on Shopify with Hydrogen
Workshop
Hydrogen is an opinionated React framework and SDK for building fast, custom storefronts powered Shopify. Hydrogen embraces React Server Components and makes use of Vite and Tailwind CSS. In this workshop participants will get a first look at Hydrogen, learn how and when to use it, all while building a fully functional custom storefront with the Hydrogen team themselves.
React Advanced Conference 2022React Advanced Conference 2022
81 min
Build a Product Page with Shopify’s Hydrogen Framework
WorkshopFree
Get hands on with Hydrogen, a React-based framework for building headless storefronts. Hydrogen is built for Shopify commerce with all the features you need for a production-ready storefront. It provides a quick start, build-fast environment so you can focus on the fun stuff - building unique commerce experiences. In this workshop we’ll scaffold a new storefront and rapidly build a product page. We’ll cover how to get started, file-based routing, fetching data from the Storefront API, Hydrogen’s built-in components and how to apply styling with Tailwind.You will know:- Get started with the hello-world template on StackBlitz- File-based routing to create a /products/example route- Dynamic routing /products/:handle- Hit the Storefront API with GraphQL- Move the query into the Hydrogen app- Update the query to fetch a product by handle- Display title, price, image & description.- Tailwind styling- Variant picker and buy now button- Bonus if there’s time: Collections page
Prerequisites: - A Chromium-based browser (StackBlitz)- Ideally experience with React. A general web development background would be fine.