ReactJS服务器端呈现与客户端呈现

问题描述 投票:93回答:4

我刚开始研究ReactJS,发现它为您提供了两种呈现页面的方法:服务器端和客户端。但是,我无法理解如何一起使用它。它是构建应用程序的两种不同方式,还是可以一起使用?

如果我们可以一起使用它,怎么做 - 我们是否需要在服务器端和客户端复制相同的元素?或者,我们可以在服务器上构建应用程序的静态部分,以及客户端上的动态部分,而不与已经预呈现的服务器端建立任何连接吗?

javascript node.js client-server reactjs
4个回答
95
投票

对于给定的网站/ Web应用程序,您可以使用客户端,服务器端或两者的响应。

Client-Side

在这里,您在浏览器上完全运行ReactJS。这是最简单的设置,包括大多数示例(包括http://reactjs.org上的示例)。服务器呈现的初始HTML是占位符,一旦加载了所有脚本,整个UI就会在浏览器中呈现。

Server-Side

将ReactJS视为服务器端模板引擎(如玉器,车把等......)。服务器呈现的HTML包含应该使用的UI,您不必等待加载任何脚本。您的页面可以被搜索引擎编入索引(如果没有执行任何javascript)。

由于UI是在服务器上呈现的,因此没有任何事件处理程序可以工作,并且没有交互性(您有一个静态页面)。

Both

这里,初始渲染在服务器上。因此,浏览器接收的HTML具有应有的UI。加载脚本后,将再次重新呈现虚拟DOM以设置组件的事件处理程序。

在这里,您需要确保使用您在服务器上呈现的相同props重新呈现完全相同的虚拟DOM(根ReactJS组件)。否则,ReactJS会抱怨服务器端和客户端虚拟DOM不匹配。

由于ReactJS在重新渲染之间区分虚拟DOM,因此真正的DOM不会发生变异。只有事件处理程序绑定到真正的DOM元素。


37
投票

图像来源:Walmart Labs Engineering Blog

SSR

CSR

注意:SSR(服务器端渲染),CSR(客户端渲染)。

主要区别在于SSR,服务器响应客户端浏览器,包括要呈现的页面的HTML。同样重要的是要注意,尽管使用SSR,页面渲染速度更快。在下载JS文件并且浏览器已执行React之前,页面将不准备用户交互。

一个缺点是SSR TTFB(第一个字节的时间)可能稍长。可以理解的是,因为服务器需要一些时间来创建HTML文档,这反过来又增加了服务器的响应大小。


3
投票

我实际上想知道相同的研究相当多,虽然你正在寻找的答案在评论中给出,但我觉得它应该更加突出,因此我正在写这篇文章(一旦我能想出一个我会更新更好的方法,因为我发现架构上的解决方案至少是有问题的)。

您需要记住两种方式编写组件,因此基本上将if开关放在任何地方以确定您是在客户端还是服务器上然后执行数据库查询(或服务器上的任何适当的)或REST调用(在客户端)。然后,您必须编写生成数据的端点并将其公开给客户端,然后就可以了。

再次,很高兴了解更清洁的解决方案。


1
投票

它是构建应用程序的两种不同方式,还是可以一起使用?

它们可以一起使用。

如果我们可以一起使用它,怎么做 - 我们是否需要在服务器端和客户端复制相同的元素?或者,我们可以在服务器上构建应用程序的静态部分,以及客户端上的动态部分,而不与已经预呈现的服务器端建立任何连接吗?

最好是渲染相同的布局以避免重排和重绘操作,减少闪烁/闪烁,您的页面将更加平滑。但是,这不是限制。你可以很好地缓存SSR html(Electrode会减少响应时间)/发送一个被CSR覆盖的静态html(客户端渲染)。

如果你刚刚开始使用SSR,我建议开始简单,SSR可以非常快速地变得非常复杂。在服务器上构建html意味着失去对窗口,文档(你在客户端上有这些)的对象的访问权限,失去合并异步操作的能力(开箱即用),并且通常需要大量的代码编辑才能使你的代码与SSR兼容(因为你必须使用webpack打包你的bundle.js)。 CSS导入,需要vs导入之类的东西突然开始咬你(在没有webpack的默认React应用中不是这种情况)。

SSR的一般模式看起来像这样。提供请求的Express服务器:

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));
}

我建议人们开始使用SSR将提供静态HTML。您可以通过运行CSR SPA应用程序获取静态html:

document.getElementById('root').innerHTML

别忘了,使用SSR的唯一原因应该是:

  1. 更快的负载(我会打折)

哈克:https://medium.com/@gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc


0
投票

服务器端呈现是最初在服务器中呈现页面的方式以及完全呈现页面如何发送回客户端的方式。

您将在此链接中获得更多详细信息。 Click here

© www.soinside.com 2019 - 2024. All rights reserved.