react 服务器端渲染_使用React进行服务器端渲染

react 服务器端渲染

Server Side Rendering, also called SSR, is the ability of a JavaScript application to render on the server rather than in the browser.

服务器端渲染 (也称为SSR )是JavaScript应用程序在服务器而不是在浏览器中进行渲染的功能。

Why would we ever want to do so?

我们为什么要这样做?

  • it allows your site to have a faster first page load time, which is the key to a good user experience

    它使您的网站拥有更快的首页加载时间,这是获得良好用户体验的关键
  • it is essential for SEO: search engines cannot (yet?) efficiently and correctly index applications that exclusively render client-side. Despite the latest improvements to indexing in Google, there are other search engines too, and Google is not perfect at it in any case. Also, Google favors sites with fast load times, and having to load client-side is not good for speed

    这对于SEO至关重要:搜索引擎无法(还?)有效且正确地索引专门呈现客户端的应用程序。 尽管Google对索引编制有了最新改进,但还有其他搜索引擎,无论如何Google都不是完美的。 另外,Google偏爱加载时间短的网站,并且必须加载客户端不利于提高速度
  • it’s great when people share a page of your site on social media, as they can easily gather the metadata needed to nicely share the link (images, title, description..)

    人们在社交媒体上共享您的网站页面时非常好,因为他们可以轻松收集很好地共享链接所需的元数据(图像,标题,描述..)

Without Server Side Rendering, all your server ships is an HTML page with no body, just some script tags that are then used by the browser to render the application.

如果没有服务器端渲染,您的所有服务器都将是一个没有正文HTML页面,只有一些脚本标签,然后浏览器就会使用这些脚本标签来渲染应用程序。

Client-rendered apps are great at any subsequent user interaction after the first page load. Server Side Rendering allows us to get the sweet spot in the middle of client-rendered apps and backend-rendered apps: the page is generated server-side, but all interactions with the page once it’s been loaded are handled client-side.

客户端呈现的应用非常适合在首页加载后进行的任何后续用户交互。 服务器端渲染使我们可以在客户端渲染的应用程序和后端渲染的应用程序的中间位置获得优势:页面是在服务器端生成的,但是与页面加载后的所有交互都在客户端处理。

However Server Side Rendering has its drawback too:

但是,服务器端渲染也有其缺点:

  • it’s fair to say that a simple SSR proof of concept is simple, but the complexity of SSR can grow with the complexity of your application

    可以说,简单的SSR概念证明很简单,但是SSR的复杂性会随着应用程序的复杂性而增加
  • rendering a big application server-side can be quite resource-intensive, and under heavy load it could even provide a slower experience than client-side rendering, since you have a single bottleneck

    在服务器端渲染大型应用程序可能会占用大量资源,并且在繁重的负载下,与客户端渲染相比,它甚至可能提供较慢的体验,因为您只有一个瓶颈

服务器端渲染React应用所需的一个非常简单的示例 (A very simplistic example of what it takes to Server-Side render a React app)

SSR setups can grow very, very complex and most tutorials will bake in Redux, React Router and many other concepts from the start.

SSR的设置可能会变得非常非常非常复杂,并且大多数教程从一开始都会涉及ReduxReact Router和许多其他概念。

To understand how SSR works, let’s start from the basics to implement a proof of concept.

为了了解SSR的工作原理,让我们从基础开始实施概念验证。

Feel free to skip this paragraph if you just want to look into the libraries that provide SSR and not bother with the ground work

如果您只想研究提供SSR的库,而不必打扰基础工作,请跳过本段

To implement basic SSR we’re going to use Express.

为了实现基本的SSR,我们将使用Express。

If you are new to Express, or need some catch-up, check out my free Express Handbook here: https://flaviocopes.com/page/ebooks/.

如果您不熟悉Express,或者需要一些帮助,请在这里查看我的免费Express Handbook: https : //flaviocopes.com/page/ebooks/

Warning: the complexity of SSR can grow with the complexity of your application. This is the bare minimum setup to render a basic React app. For more complex needs you might need to do a bit more work or also check out SSR libraries for React.

警告:SSR的复杂性会随着应用程序的复杂性而增加。 这是渲染基本React应用程序的最低要求。 对于更复杂的需求,您可能需要做更多的工作,或者还检查React的SSR库。

I assume you started a React app with create-react-app. If you are just trying, install one now using npx create-react-app ssr.

我假设您使用create-react-app启动了一个React create-react-app 。 如果您只是尝试,请立即使用npx create-react-app ssr安装一个。

Go to the main app folder with the terminal, then run:

使用终端转到主应用程序文件夹,然后运行:

npm install express

You have a set of folders in your app directory. Create a new folder called server, then go into it and create a file named server.js.

您的应用程序目录中有一组文件夹。 创建一个名为server的新文件夹,然后进入其中并创建一个名为server.js的文件。

Following the create-react-app conventions, the app lives in the src/App.js file. We’re going to load that component, and render it to a string using ReactDOMServer.renderToString(), which is provided by react-dom.

遵循create-react-app约定,该应用程序位于src/App.js文件中。 我们将加载该组件,并使用react-dom提供的ReactDOMServer.renderToString()将其呈现为字符串。

You get the contents of the ./build/index.html file, and replace the <div id="root"></div> placeholder, which is the tag where the application hooks by default, with `<div id="root">\${ReactDOMServer.renderToString(<App />)}</div>.

你得到的内容./build/index.html文件,并替换<div id="root"></div>占位符,其是标签,其中默认的应用钩子,与` <div id="root">\${ReactDOMServer.renderToString(<App />)}</div>

All the content inside the build folder is going to be served as-is, statically by Express.

Express会按原样提供build文件夹中的所有内容。

import path from 'path'
import fs from 'fs'

import express from 'express'
import React from 'react'
import ReactDOMServer from 'react-dom/server'

import App from '../src/App'

const PORT = 8080
const app = express()

const router = express.Router()

const serverRenderer = (req, res, next) => {
  fs.readFile(path.resolve('./build/index.html'), 'utf8', (err, data) => {
    if (err) {
      console.error(err)
      return res.status(500).send('An error occurred')
    }
    return res.send(
      data.replace(
        '<div id="root"></div>',
        `<div id="root">${ReactDOMServer.renderToString(<App />)}</div>`
      )
    )
  })
}
router.use('^/$', serverRenderer)

router.use(
  express.static(path.resolve(__dirname, '..', 'build'), { maxAge: '30d' })
)

// tell the app to use the above rules
app.use(router)

// app.use(express.static('./build'))
app.listen(PORT, () => {
  console.log(`SSR running on port ${PORT}`)
})

Now, in the client application, in your src/index.js, instead of calling ReactDOM.render():

现在,在客户端应用程序中,在您的src/index.js ,而不是调用ReactDOM.render()

ReactDOM.render(<App />, document.getElementById('root'))

call ReactDOM.hydrate(), which is the same but has the additional ability to attach event listeners to existing markup once React loads:

调用ReactDOM.hydrate() ,这是相同的,但是具有额外的功能,一旦React加载,便可以将事件侦听器附加到现有标记:

ReactDOM.hydrate(<App />, document.getElementById('root'))

All the Node.js code needs to be transpiled by Babel, as server-side Node.js code does not know anything about JSX, nor ES Modules (which we use for the include statements).

所有的Node.js代码都需要由Babel编译,因为服务器端Node.js代码对JSX或ES模块(我们用于include语句)一无所知。

Install these 4 packages:

安装以下4个软件包:

npm install @babel/register @babel/preset-env @babel/preset-react ignore-styles

ignore-styles is a Babel utility that will tell it to ignore CSS files imported using the import syntax.

ignore-styles是Babel实用程序,它将告诉它忽略使用import语法导入CSS文件。

Let’s create an entry point in server/index.js:

让我们在server/index.js创建一个入口点:

require('ignore-styles')

require('@babel/register')({
  ignore: [/(node_modules)/],
  presets: ['@babel/preset-env', '@babel/preset-react']
})

require('./server')

Build the React application, so that the build/ folder is populated:

编译React应用程序,以填充build /文件夹:

npm run build

and let’s run this:

让我们运行这个:

node server/index.js

I said this is a simplistic approach, and it is:

我说这是一种简单的方法,它是:

  • it does not handle rendering images correctly when using imports, which need Webpack in order to work (and which complicates the process a lot)

    使用导入时,它不能正确处理渲染图像,而导入需要Webpack才能正常工作(这使整个过程变得非常复杂)
  • it does not handle page header metadata, which is essential for SEO and social sharing purposes (among other things)

    它不处理页面标题元数据,这对于SEO和社交共享目的非常重要(除其他事项外)

So while this is a good example of using ReactDOMServer.renderToString() and ReactDOM.hydrate to get this basic server-side rendering, it’s not enough for real world usage.

因此,尽管这是一个使用ReactDOMServer.renderToString()ReactDOM.hydrate来获取基本服务器端渲染的很好的示例,但对于实际使用而言还不够。

使用库的服务器端渲染 (Server Side Rendering using libraries)

SSR is hard to do right, and React has no de-facto way to implement it.

SSR很难做到正确,而且React没有实际的方法来实现它。

It’s still very much debatable if it’s worth the trouble, complication and overhead to get the benefits, rather than using a different technology to serve those pages. This discussion on Reddit has lots of opinions in that regard.

如果值得付出麻烦,复杂化和开销来获得好处,而不是使用其他技术来提供这些页面,那还是值得商de的。 关于Reddit的讨论在这方面有很多意见。

When Server Side Rendering is an important matter, my suggestion is to rely on pre-made libraries and tools that have had this goal in mind since the beginning.

当服务器端渲染很重要时,我的建议是依赖从一开始就牢记此目标的预制库和工具。

In particular, I suggest Next.js and Gatsby.

特别是,我建议使用Next.jsGatsby

翻译自: https://flaviocopes.com/react-server-side-rendering/

react 服务器端渲染

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值