React SSR 服务器端渲染

React SSR 介绍

什么是客户端渲染

CSR: Client Side Rendering
服务器端仅返回 JSON 数据,DATA 和 HTML 在客户端进行渲染

什么是服务器端渲染

SSR: Server Side Rendering
服务器端返回 HTML,DATA 和 HTML在服务器端渲染

客户端渲染存在的问题

  1. 首屏等待时间长,用户体验差
  2. 首页结构为空,不利于 SEO

SPA 应用中服务器端渲染解决的问题
React SSR 服务器端渲染_第1张图片React SSR 服务器端渲染_第2张图片
React SSR 同构

同构指的是代码复用,即实现客户端和服务器端最大程度的代码复用

服务器端渲染快速开始

项目结构
React SSR 服务器端渲染_第3张图片
创建 Node 服务器

import express from 'express';

const app = express();

app.use(express.static('public'));

app.listen(3000, () => console.log('app is running on 3000 port'));

export default app;

实现 React SSR

  1. 引入要渲染的 React 组件

  2. 通过 renderToString 方法将 React 组件转换为 HTML 字符串

  3. 将 Html 字符串想到客户端

    renderToString 方法用于将 React 组件转换为 HTML 字符串,通过 react-dom/server 导入

Webpack 打包配置

问题: Node环境不支持 EsModule 模块系统,不支持 JSX 语法

项目启动命令配置

  1. 配置服务器端打包命令:
    "dev:server-build": "webpack --config webpack.server.js --watch",
    
  2. 配置服务器端启动命令:
    "dev:server-run": "nodemon --watch build --exec \"node build/bundle.js\"",
    

客户端 React 附加事件

实现思路分析
在客户端对组件进行二次“渲染”,为组件元素附加事件
React SSR 服务器端渲染_第4张图片
React SSR 服务器端渲染_第5张图片
React SSR 服务器端渲染_第6张图片
React SSR 服务器端渲染_第7张图片

优化

合并 Webpack 配置
React SSR 服务器端渲染_第8张图片
合并项目启动命令

目的:使用一个命令启动项目,解决多个命令启动的繁琐问题。通过 npm-run-all 工具实现

"dev": "npm-run-all --parallel dev:*",

服务器端打包文件体积优化

问题:在服务器端打包文件中,包含了Node系统模块。导致打包文件本身体积庞大。
解决:通过 Webpak 配置剔除打包文件中的 Node 模块。

// webpack.server.js
const nodeExternals = require('webpack-node-externals');

const config = {
  externals: [nodeExternals()]
}

将启动服务器代码和渲染代码进行模块化拆分

优化代码组织方式,渲染 React 组件代码是独立功能,所以把它从服务器端入口文件中进行抽离。

路由支持

实现思路分析

  • 在 React SRR 项目中需要实现两端路由
  • 客户端路由是用于支持用户通过点击链接的方式跳转页面
  • 服务器端路由是用于支持用户直接从浏览器地址栏中访问页面
  • 客户端和服务器端共用一套路由规则

编写路由规则

import Home from '../share/pages/Home';
import List from '../share/pages/List';

export default [{
  path: '/',
  component: Home,
  exact: true
}, {
  path: '/list',
  ...List
}]

实现服务器端路由

  1. Express 路由接收任何请求
    Express 路由接收所有 get 请求,服务器 React 路由通过请求路径匹配要进行渲染的组件

     app.get('*', (req, res) => {});
    
  2. 服务器端路由配置
    React SSR 服务器端渲染_第9张图片
    实现客户端路由

    添加客户端路由配置
    React SSR 服务器端渲染_第10张图片

Redux 支持

实现思路分析

  • 在实现 React SSR 的项目中需要实现两端的 Redux
  • 客户端 Redux 就是通过客户端 JavaScript 管理 Store 中的数据
  • 服务器端 Redux 就是在服务器端搭建一套 Redux 代码,用于管理组件中的数据
  • 客户端和服务器端共用一套 Redux 代码
  • 创建 Store 的代码由于参数传递的不同所以不可以共用

实现客户端 Redux

  • 创建 Store
  • 配置 Store
  • 创建 Action 和 Reducer
  • 配置 polyfill (由于浏览器不能识别异步代码,所以要 polyfill 来填充)

实现服务器端 Redux

  • 创建 Store
    React SSR 服务器端渲染_第11张图片
  • 配置 Store
    React SSR 服务器端渲染_第12张图片React SSR 服务器端渲染_第13张图片

服务器端 Store 数据填充

问题:服务器端创建的 store 是空的,组件并不能从 store 中获取到任何数据
解决:服务器端在渲染组件之前获取到组件所需要的数据
  • 在组件中添加 LoadData 方法,此方法用于获取组件所需的数据,方法被服务器端调用
  • 将 LoadData 方法保存在当前组件的路由对象信息中
  • 服务器端在接收到请求后,根据请求地址匹配出要渲染的组件的路由信息
  • 从路由信息中获取组件中的 LoadData 方法并调用方法获取组件所需数据
  • 当数据获取完成以后再渲染组件并将结果响应到客户端

React SSR 服务器端渲染_第14张图片
React SSR 服务器端渲染_第15张图片
React 消除警告

警告原因:客户端 Store 在初始状态下是没有数据的,在渲染组件的时候生成的是空 ul ,但服务器端是先获取数据再进行的组件渲染,所以生成的是有子元素的 ul, hydrate 方法在对比的时候发现两者不一致,所以报了个警告。

解决思路:将服务器端获取到的数据回填给客户端,让客户端拥有初始数据

  • 服务器响应 Store 初始状态
    React SSR 服务器端渲染_第16张图片
  • 客户端设置 Store 初始状态
    React SSR 服务器端渲染_第17张图片

防范 XSS 攻击

  • 转义状态中的恶意代码
    React SSR 服务器端渲染_第18张图片

你可能感兴趣的:(笔记,React,react)