简体   繁体   English

ReactJS 服务器端渲染与客户端渲染

[英]ReactJS server-side rendering vs client-side rendering

I just have began to study ReactJS and found that it gives you 2 ways to render pages: server-side and client-side.我刚刚开始研究 ReactJS,发现它为您提供了两种渲染页面的方式:服务器端和客户端。 But, I can't understand how to use it together.但是,我无法理解如何一起使用它。 Is it 2 separate ways to build the application, or can they be used together?是两种不同的方式来构建应用程序,还是可以一起使用?

If we can use it together, how to do it - do we need to duplicate the same elements on the server side and client side?如果我们可以一起使用它,怎么做 - 我们是否需要在服务器端和客户端复制相同的元素? Or, can we just build the static parts of our application on the server, and the dynamic parts on the client side, without any connection to the server side that was already pre-rendered?或者,我们是否可以只在服务器上构建应用程序的静态部分,在客户端构建动态部分,而无需连接到已经预渲染的服务器端?

For a given website / web-application, you can use react either client-side , server-side or both .对于给定的网站/网络应用程序,您可以使用 react客户端服务器端两者

Client-Side客户端

Over here, you are completely running ReactJS on the browser.在这里,您完全在浏览器上运行 ReactJS。 This is the simplest setup and includes most examples (including the ones on http://reactjs.org ).这是最简单的设置,包括大多数示例(包括http://reactjs.org上的示例)。 The initial HTML rendered by the server is a placeholder and the entire UI is rendered in the browser once all your scripts load.服务器呈现的初始 HTML 是一个占位符,一旦所有脚本加载完毕,整个 UI 就会在浏览器中呈现。

Server-Side服务器端

Think of ReactJS as a server-side templating engine here (like jade, handlebars, etc...).将 ReactJS 视为这里的服务器端模板引擎(如 jade、把手等......)。 The HTML rendered by the server contains the UI as it should be and you do not wait for any scripts to load.服务器呈现的 HTML 包含应有的 UI,您无需等待任何脚本加载。 Your page can be indexed by a search engine (if one does not execute any javascript).您的页面可以被搜索引擎编入索引(如果不执行任何 javascript)。

Since the UI is rendered on the server, none of your event handlers would work and there's no interactivity (you have a static page).由于 UI 是在服务器上呈现的,因此您的任何事件处理程序都不会工作,并且没有交互性(您有一个静态页面)。

Both两个都

Here, the initial render is on the server.在这里,初始渲染在服务器上。 Hence, the HTML received by the browser has the UI as it should be.因此,浏览器接收到的 HTML 具有应有的 UI。 Once the scripts are loaded, the virtual DOM is re-rendered once again to set up your components' event handlers.加载脚本后,虚拟 DOM 将再次重新渲染以设置组件的事件处理程序。

Over here, you need to make sure that you re-render the exact same virtual DOM (root ReactJS component) with the same props that you used to render on the server.在这里,您需要确保使用在服务器上渲染的相同props重新渲染完全相同的虚拟 DOM(根 ReactJS 组件)。 Otherwise, ReactJS will complain that the server-side and client-side virtual DOMs don't match.否则,ReactJS 会抱怨服务器端和客户端虚拟 DOM 不匹配。

Since ReactJS diffs the virtual DOMs between re-renders, the real DOM is not mutated.由于 ReactJS 在重新渲染之间区分虚拟 DOM,因此真实 DOM 不会发生变异。 Only the event handlers are bound to the real DOM elements.只有事件处理程序绑定到真正的 DOM 元素。

Image source: Walmart Labs Engineering Blog图片来源: 沃尔玛实验室工程博客

固态继电器

企业社会责任

NB: SSR (Server Side Rendering), CSR (Client Side Rendering).注意: SSR (服务器端渲染)、 CSR (客户端渲染)。

The main difference being that with SSR, the servers response to the clients browser, includes the HTML of the page to be rendered.与 SSR 的主要区别在于,服务器对客户端浏览器的响应包括要呈现的页面的 HTML。 It is also important to note that although, with SSR, the page renders quicker.同样重要的是要注意,尽管使用 SSR,页面呈现速度更快。 The page will not be ready for user interaction until JS files have been downloaded and the browser has executed React.在下载 JS 文件并且浏览器执行 React 之前,页面不会为用户交互做好准备。

One downside is that the SSR TTFB (Time to First Byte) can be slightly longer.一个缺点是 SSR TTFB(第一个字节的时间)可能会稍长一些。 Understandably so, because the server takes some time creating the HTML document, which in turn increases the servers response size.可以理解,因为服务器需要一些时间来创建 HTML 文档,这反过来会增加服务器响应的大小。

I was actually wondering the same researching quite a bit and while the answer you are looking for was given in the comments but I feel it should be more prominent hence I'm writing this post (which I will update once I can come up with a better way as I find the solution architecturally at least questionable).我实际上很想知道同样的研究,虽然你正在寻找的答案在评论中给出,但我觉得它应该更加突出,因此我正在写这篇文章(一旦我能想出一个我会更新更好的方法,因为我发现解决方案在架构上至少是有问题的)。

You would need to write your components with both ways in mind thus basically putting if switches everywhere to determine whether you are on the client or the server and then do either as DB query (or whatever appropriate on the server) or a REST call (on the client).您需要同时考虑两种方式来编写组件,因此基本上将if开关放在任何地方以确定您是在客户端还是服务器上,然后作为 DB 查询(或服务器上的任何适当内容)或 REST 调用(在客户端)。 Then you would have to write endpoints which generate your data and expose it to the client and there you go.然后,您必须编写生成数据并将其公开给客户端的端点,然后就可以了。

Again, happy to learn about a cleaner solution.再次,很高兴了解更清洁的解决方案。

Is it 2 separate ways to build the application, or can they be used together?是两种不同的方式来构建应用程序,还是可以一起使用?

They can be used together.它们可以一起使用。

If we can use it together, how to do it - do we need to duplicate the same elements on the server side and client side?如果我们可以一起使用它,怎么做 - 我们是否需要在服务器端和客户端复制相同的元素? Or, can we just build the static parts of our application on the server, and the dynamic parts on the client side, without any connection to the server side that was already pre-rendered?或者,我们是否可以只在服务器上构建应用程序的静态部分,在客户端构建动态部分,而无需连接到已经预渲染的服务器端?

It's better to have the same layout being rendered to avoid reflow and repaint operations, less flicker / blinks, your page will be smoother.最好呈现相同的布局以避免回流和重绘操作,减少闪烁/闪烁,您的页面会更流畅。 However, it's not a limitation.但是,这不是限制。 You could very well cache the SSR html (something Electrode does to cut down response time) / send a static html which gets overwritten by the CSR (client side render).您可以很好地缓存 SSR html( Electrode为缩短响应时间所做的事情)/发送静态 html,该 html 会被 CSR(客户端渲染)覆盖。

If you're just starting with SSR, I would recommend start simple, SSR can get very complex very quickly.如果您刚开始使用 SSR,我建议从简单开始,SSR 会很快变得非常复杂。 To build html on the server means losing access to objects like window, document (you have these on the client), losing ability to incorporate async operations (out of the box), and generally lots of code edits to get your code SSR compatible (since you'll have to use webpack to pack your bundle.js).在服务器上构建 html 意味着无法访问窗口、文档等对象(客户端上有这些),无法合并异步操作(开箱即用),并且通常需要进行大量代码编辑以使您的代码 SSR 兼容(因为你必须使用 webpack 来打包你的 bundle.js)。 Things like CSS imports, require vs import suddenly start biting you (this is not the case in default React app without webpack).像 CSS 导入、require 和 import 之类的东西突然开始让你感到厌烦(在没有 webpack 的默认 React 应用程序中,情况并非如此)。

The general pattern of SSR looks like this. SSR 的一般模式是这样的。 An Express server serving requests:服务请求的 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));
}

My suggestion to folks starting out with SSR would be to serve out static html.我对开始使用 SSR 的人的建议是提供静态 html。 You can get the static html by running the CSR SPA app:您可以通过运行 CSR SPA 应用程序来获取静态 html:

document.getElementById('root').innerHTML

Don't forget, the only reasons to use SSR should be:不要忘记,使用 SSR 的唯一原因应该是:

  1. SEO搜索引擎优化
  2. Faster loads (I would discount this)更快的加载(我会打折扣)

Hack : https://medium.com/@gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc黑客: https : //medium.com/@gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc

Server side rendering is the way how you render the page initially in server and how the fully rendered page is send back to client. 服务器端渲染是您最初在服务器中渲染页面以及将完全渲染的页面发送回客户端的方式。

You will get more in depth details in this link. 您将在此链接中获得更多详细信息。 Click here 点击这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用服务器端和客户端渲染的单页ReactJS应用程序? - Single-page ReactJS app using both server-side and client-side rendering? 客户端和服务器端呈现的模板语言 - Templating language for both client-side and server-side rendering ReactJS服务器端渲染似乎并没有改变客户端的情况 - Reactjs server-side rendering seems to not change a thing on the client side ReactJS服务器端渲染问题 - ReactJS server-side rendering issue ReactJS服务器端渲染,setTimeout问题 - ReactJS server-side rendering, setTimeout issue 您如何判断网页是客户端渲染还是服务器端渲染 - How do you tell if a web page is client-side or server-side rendering 如何在node / express和Backbone中混合混合(服务器端和客户端渲染)? - How to mix hybrid (server-side and client-side rendering) in node/express and Backbone? 使用客户端和服务器端呈现来反应同构组件 - React isomorphic component with both client-side and server-side rendering 在服务器端和客户端渲染之后如何操作 DOM? - How to manipulate DOM both after server-side and client-side rendering? 在服务器端进行React组件渲染,但客户端不会接管 - React component rendering on server-side, but client-side does not take over
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM