Representación del lado del servidor de ReactJS frente a representación del lado del cliente

7 minutos de lectura

avatar de usuario
Simjá

Acabo de empezar a estudiar ReactJS y descubrí que ofrece 2 formas de renderizar páginas: del lado del servidor y del lado del cliente. Pero, no puedo entender cómo usarlo juntos. ¿Son 2 formas separadas de construir la aplicación, o se pueden usar juntas?

Si podemos usarlo juntos, ¿cómo hacerlo? ¿Necesitamos duplicar los mismos elementos en el lado del servidor y en el lado del cliente? O, ¿podemos simplemente construir las partes estáticas de nuestra aplicación en el servidor y las partes dinámicas en el lado del cliente, sin ninguna conexión con el lado del servidor que ya estaba renderizado previamente?

  • Respuesta corta, NO: puede desacoplar, enviar html estático y cambiarlo por completo en el renderizado del cliente. He agregado detalles en mi respuesta.

    – Kira

    15 de febrero de 2019 a las 18:50

avatar de usuario
Gautham Badhrinathan

Para un sitio web/aplicación web dado, puede usar reaccionar ya sea lado del cliente, lado del servidor o ambas cosas.

Lado del cliente

Aquí, está ejecutando completamente ReactJS en el navegador. Esta es la configuración más simple e incluye la mayoría de los ejemplos (incluidos los de http://reactjs.org). El HTML inicial representado por el servidor es un marcador de posición y toda la interfaz de usuario se representa en el navegador una vez que se cargan todos los scripts.

Lado del servidor

Piense en ReactJS como un motor de plantillas del lado del servidor aquí (como jade, manillares, etc.). El HTML presentado por el servidor contiene la interfaz de usuario como debería ser y no espera a que se cargue ningún script. Su página puede ser indexada por un motor de búsqueda (si uno no ejecuta ningún javascript).

Dado que la interfaz de usuario se representa en el servidor, ninguno de sus controladores de eventos funcionaría y no hay interactividad (tiene una página estática).

Ambas cosas

Aquí, el renderizado inicial está en el servidor. Por lo tanto, el HTML recibido por el navegador tiene la interfaz de usuario como debería ser. Una vez que se cargan los scripts, el DOM virtual se vuelve a renderizar una vez más para configurar los controladores de eventos de sus componentes.

Aquí, debe asegurarse de volver a renderizar exactamente el mismo DOM virtual (componente raíz de ReactJS) con el mismo props que usó para renderizar en el servidor. De lo contrario, ReactJS se quejará de que los DOM virtuales del lado del servidor y del lado del cliente no coinciden.

Dado que ReactJS diferencia los DOM virtuales entre renderizaciones, el DOM real no se muta. Solo los controladores de eventos están vinculados a los elementos DOM reales.

  • Entonces, en el caso de “ambos”, necesito escribir el mismo código dos veces, uno para la representación del servidor y otro para reproducir este DOM en el cliente, ¿verdad?

    – Simjá

    4 de diciembre de 2014 a las 11:18

  • Necesitas correr el mismo código dos veces. Una vez en el servidor y una vez en el cliente. Sin embargo, debe escribir sus componentes para tener esto en cuenta; por ejemplo, no debe realizar ninguna recuperación de datos asíncrona en componentWillMount(), ya que ejecutará tanto el cliente como el servidor. También necesitará una estrategia para obtener datos por adelantado en el servidor y ponerlos a disposición para el renderizado inicial en el cliente, para asegurarse de obtener el mismo resultado.

    – Jonny Buchanan

    4 de diciembre de 2014 a las 11:51

  • También puede verificar si el código que se ejecuta está en el lado del servidor o en el lado del cliente usando typeof window == "undefined" y luego obtenga sus datos en consecuencia.

    – Gautham Badhrinathan

    5 de diciembre de 2014 a las 0:11

  • ¿Tiene un enlace a un ejemplo que se ajuste a su implementación?

    –Kevin Ghadyani

    10 de febrero de 2016 a las 2:22

  • @IanW Por lo general, en este caso, el HTML devuelto por el servidor es muy “básico”, simplemente importa su JavaScript y estilos y contiene un <div> en el que React escribirá.

    – Matt Holanda

    20 de septiembre de 2016 a las 0:04

avatar de usuario
JSON C11

Fuente de imagen: Blog de ingeniería de laboratorios de Walmart

RSS

RSE

NÓTESE BIEN: RSS (Representación del lado del servidor), RSE (Representación del lado del cliente).

La principal diferencia es que con SSR, la respuesta del servidor al navegador del cliente incluye el HTML de la página que se representará. También es importante tener en cuenta que, aunque con SSR, la página se procesa más rápido. La página no estará lista para la interacción del usuario hasta que se hayan descargado los archivos JS y el navegador haya ejecutado React.

Una desventaja es que el SSR TTFB (Tiempo hasta el primer byte) puede ser un poco más largo. Comprensiblemente, porque el servidor tarda un tiempo en crear el documento HTML, lo que a su vez aumenta el tamaño de respuesta del servidor.

De hecho, me preguntaba lo mismo investigando un poco y, aunque la respuesta que está buscando se dio en los comentarios, pero creo que debería ser más prominente, por lo tanto, estoy escribiendo esta publicación (que actualizaré una vez que pueda encontrar un mejor manera ya que encuentro la solución arquitectónicamente al menos cuestionable).

Necesitarías escribir tus componentes con ambos caminos en mente básicamente poniendo if cambia en todas partes para determinar si está en el cliente o en el servidor y luego realiza una consulta de base de datos (o lo que sea apropiado en el servidor) o una llamada REST (en el cliente). Luego, tendría que escribir puntos finales que generen sus datos y exponerlos al cliente y listo.

Nuevamente, feliz de aprender acerca de una solución más limpia.

¿Son 2 formas separadas de construir la aplicación, o se pueden usar juntas?

Se pueden usar juntos.

Si podemos usarlo juntos, ¿cómo hacerlo? ¿Necesitamos duplicar los mismos elementos en el lado del servidor y en el lado del cliente? O, ¿podemos simplemente construir las partes estáticas de nuestra aplicación en el servidor y las partes dinámicas en el lado del cliente, sin ninguna conexión con el lado del servidor que ya estaba renderizado previamente?

Es mejor tener el mismo diseño renderizado para evitar operaciones de reflujo y repintado, menos parpadeos/parpadeos, su página será más fluida. Sin embargo, no es una limitación. Podría muy bien almacenar en caché el SSR html (algo Electrodo hace para reducir el tiempo de respuesta) / enviar un html estático que se sobrescribe con la CSR (representación del lado del cliente).

Si recién está comenzando con SSR, recomendaría comenzar de manera simple, SSR puede volverse muy complejo muy rápidamente. Construir html en el servidor significa perder el acceso a objetos como ventana, documento (los tiene en el cliente), perder la capacidad de incorporar operaciones asíncronas (listas para usar) y, en general, muchas ediciones de código para que su código sea compatible con SSR ( ya que tendrás que usar webpack para empaquetar tu bundle.js). Cosas como las importaciones de CSS, require vs import de repente comienzan a morderte (este no es el caso en la aplicación React predeterminada sin paquete web).

El patrón general de SSR se ve así. Un servidor Express que atiende solicitudes:

const app = Express();
const port = 8092;

// This is fired every time the server side receives a request
app.use(handleRender);
function handleRender(req, res) {
    const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
    console.log('fullUrl: ', fullUrl);
    console.log('req.url: ', req.url);

    // Create a new Redux store instance
    const store = createStore(reducerFn);

    const urlToRender = req.url;
    // Render the component to a string
    const html = renderToString(
        <Provider store={store}>
            <StaticRouter location={urlToRender} context={{}}>
                {routes}
            </StaticRouter>
        </Provider>
    );
    const helmet = Helmet.renderStatic();

    // Grab the initial state from our Redux store
    const preloadedState = store.getState();

    // Send the rendered page back to the client
    res.send(renderFullPage(helmet, html, preloadedState));
}

Mi sugerencia para las personas que comienzan con SSR sería servir html estático. Puede obtener el html estático ejecutando la aplicación CSR SPA:

document.getElementById('root').innerHTML

No olvide que las únicas razones para usar SSR deben ser:

  1. SEO
  2. Cargas más rápidas (descontaría esto)

Cortar a tajos : https://medium.com/@gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc

¿Ha sido útil esta solución?