What is server-side rendering? How to do this with React?
Server-side rendering, is also calledsolid state relay, Is the function of the JavaScript application rendered in the server rather than in the browser.
Why do we do this?
- It makes your website have a faster homepage loading time, which is the key to a good user experience
- This is essential for SEO: search engines cannot (yet?) efficiently and correctly index applications that are dedicated to the client. Although Google has made the latest improvements to indexing, there are other search engines, and Google is not perfect anyway. In addition, Google prefers websites with short loading times, and having to load the client is not conducive to improving speed
- It’s great when people share your website pages on social media because they can easily collect the metadata (images, titles, descriptions...) needed to share links well.
If there is no server-side rendering, all your servers will be an HTML page with no body and only some script tags, and then the browser will use these script tags to render the application.
Client-side rendered applications are ideal for any subsequent user interactions after the first page is loaded. Server-side rendering allows us to gain an advantage in the middle of the application rendered on the client side and the application rendered on the back-end: the page is generated on the server side, but all interactions with the page after it is loaded are processed on the client side.
However, server-side rendering also has its disadvantages:
- It can be said that a simple SSR proof of concept is simple, but the complexity of SSR will increase with the complexity of the application
- Rendering large applications on the server side may take up a lot of resources, and under heavy load, it may even provide a slower experience compared to client-side rendering because you have only one bottleneck
A very simple example for server-side rendering of React applications
SSR settings can become very, very complicated, and most tutorials will introduceRedux,Reaction routerAnd many other concepts from the beginning.
In order to understand the working principle of SSR, let us start with the basic knowledge to implement proof of concept.
If you only want to study the library that provides SSR without disturbing the basic work, please skip this section
To implement basic SSR, we will use Express.
If you are not familiar with Express, or need some help, please check my free Express Handbook here:https://flaviocopes.com/page/ebooks/.
Warning: The complexity of SSR will increase with the complexity of the application. This is the minimum requirement for rendering basic React applications. For more complex requirements, you may need to do more work, or also check React's SSR library.
I assume you started a React application using the following methodcreate-react-app
. If you are just trying, use install nownpx create-react-app ssr
.
Use the terminal to go to the main application folder and run:
npm install express
There is a set of folders in your application directory. Create a new folder namedserver
, Then enter it and create a file calledserver.js
.
Followingcreate-react-app
By convention, the application is located atsrc/App.js
file. We will load the component and useReactDOMServer.renderToString(),Provided by thereact-dom
.
What you get./build/index.html
File, then replace<div id="root"></div>
Placeholder, it is a label attached by default to the application, with `<div id="root">\${ReactDOMServer.renderToString(<App />)}</div>
.
Everything insidebuild
Express will provide the folder as is.
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"></span><span style="color:#e6db74">${</span><span style="color:#a6e22e">ReactDOMServer</span>.<span style="color:#a6e22e">renderToString</span>(<span style="color:#f92672"><</span><span style="color:#a6e22e">App</span> <span style="color:#f92672">/></span>)<span style="color:#e6db74">}</span><span style="color:#e6db74"></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 </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">PORT</span><span style="color:#e6db74">}</span><span style="color:#e6db74">
)
})
Now in the client applicationsrc/index.js
Instead of callingReactDOM.render()
:
ReactDOM.render(<App />, document.getElementById('root'))
callReactDOM.hydrate()
The same, but once React loads, it also has the additional function of attaching event listeners to existing tags:
ReactDOM.hydrate(<App />, document.getElementById('root'))
All Node.js code needs to beTower of Babel, Because the server-side Node.js code does not understand JSX, nor does it understand ES modules (we useinclude
statement).
Install the following 4 packages:
npm install @babel/register @babel/preset-env @babel/preset-react ignore-styles
ignore-styles
Is the Babel utility, it will tell it to ignore the use ofimport
syntax.
Let's create an entry point inserver/index.js
:
require('ignore-styles')
require(’@babel/register’)({
ignore: [/(node_modules)/],
presets: [’@babel/preset-env’, ‘@babel/preset-react’]
})
require(’./server’)
Compile the React application to fill the build/ folder:
npm run build
Let's run this:
node server/index.js
I said this is a simple method, it is:
- When using import, it cannot process the rendered image correctly, and the import requires Webpack to work properly (this makes the whole process very complicated)
- It does not handle page header metadata, which is very important for SEO and social sharing purposes (among other things)
So while this is a good example of usingReactDOMServer.renderToString()
withReactDOM.hydrate
To obtain this basic server-side rendering effect, it is not enough for actual use.
Server-side rendering using the library
SSR is difficult to get right, and React has no practical way to achieve it.
If it is worth the trouble, complication, and overhead to get the benefits, instead of using other technologies to provide these pages, then it is worth discussing.Discussion on RedditThere are many opinions in this regard.
When server-side rendering is important, my advice is to rely on pre-built libraries and tools that keep this goal in mind from the beginning.
I especially recommendNext.jswithGatsby.
Download mine for freeResponse Handbook
More response tutorials:
- A simple React application example: Get GitHub user information through API
- Build a simple counter with React
- VS Code setup for React development
- How to pass props to child components through React Router
- Create an application using Electron and React
- Tutorial: Create a spreadsheet with React
- Roadmap for learning React
- Learn how to use Redux
- Getting started with JSX
- Stylized components
- Introduction to Redux Saga
- Introduction to React Router
- Introduction to React
- Reaction component
- Virtual DOM
- Reaction event
- Reaction state
- Reaction props
- Reaction fragment
- React Context API
- Reaction PropTypes
- Reaction Concept: Declarative
- React: How to display other components when clicked
- How to loop inside React JSX
- Props and status in React
- Should you use jQuery or React?
- How much JavaScript do I need to know to use React?
- Gatsby Introduction
- How to reference DOM elements in React
- One-way data flow in React
- React high-end components
- React to life cycle events
- Reaction concept: immutability
- Reaction concept: purity
- Introduction to React hooks
- Introduction to create-react-app
- Reaction concept: composition
- React: demo component and container component
- Code splitting in React
- Server-side rendering with React
- How to install React
- CSS in React
- Use SASS in React
- Processing forms in React
- Reaction strict mode
- Reaction portal
- React rendering props
- Test React components
- How to pass parameters to event handlers in React
- How to deal with errors in React
- How to return multiple elements in JSX
- Conditional rendering in React
- Reaction, how to transfer props to subcomponents
- How to get the value of an input element in React
- How to use useState React hook
- How to use useCallback React hook
- How to use useEffect React hook
- How to use useMemo React hook
- How to use useRef React hook
- How to use useContext React hook
- How to use useReducer React hook
- How to connect your React app to the backend of the same source
- Reaching the router tutorial
- How to use React Developer Tools
- How to learn React
- How to debug a React application
- How to render HTML in React
- How to fix `dangerouslySetInnerHTML` does not match the error in React
- How can I solve the problem of React login form status and browser auto-fill
- How to configure HTTPS in React application on localhost
- How to fix the "Component cannot be updated while rendering other components" error in React
- Can I use React hooks within the conditions?
- Using useState with objects: how to update
- How to move in code blocks using React and Tailwind
- React, focus on an item in React when added to the DOM
- Response, edit text on doubleclick