【redux】详解react/redux的服务端渲染:页面性能与SEO
亟待解决的疑问
为什么服务端渲染首屏渲染快?(对比客户端首屏渲染)
为什么服务端渲染有利于SEO?(对比客户端渲染)


服务端渲染的具体的代码


export const increment = () => {
return { type:'INCREMENT' }
}
export const decrement = () => {
return { type:'DECREMENT' }
}
import { combineReducers } from 'redux'
const initState = { number:0 }
const counterReducer = (state = initState, action) => {
const { number } = state
switch (action.type) {
case 'INCREMENT':
return { number:number + 1}
case 'DECREMENT':
return { number:number - 1}
default:
return state
}
}
export default combineReducers({ counterReducer })
import { createStore } from 'redux'
import reducer from '../reducer'
export default (preloadedState={}) => {
const store = createStore(
reducer,
preloadedState
)
return store
}
import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import ComponentApp from '../component'
import * as NumberActions from '../action' const mapStateToProps = state => {
return { number:state.counterReducer.number }
} const mapDispatchToProps = dispatch => {
return bindActionCreators(NumberActions,dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(ComponentApp)
import React from 'react'
class ComponentApp extends React.Component{
render () {
const { number, increment, decrement } = this.props
return (
<div>
<h1>{number}</h1>
<button onClick={increment}>增1</button>
<button onClick={decrement}>减1</button>
</div>
)
}
}
export default ComponentApp
import React from 'react'
import path from'path'
import ReactDOMServer from 'react-dom/server'
import { Provider } from 'react-redux' import createStore from '../common/store'
import App from '../common/container' /************ 这部分代码参考自webpack-dev-middleware的官方文档 ************/
var express = require("express");
var webpackDevMiddleware = require("webpack-dev-middleware");
var webpack = require("webpack");
var webpackConfig = require('../../webpack.config.js'); var app = express(); var compiler = webpack(webpackConfig);
app.use(webpackDevMiddleware(compiler, {
// 这个publicPath参数要和webpack.config.js的`output.publicPath`参数保持一致
publicPath:webpackConfig.output.publicPath
})); /************ 这部分代码参考自webpack-dev-middlemare的官方文档 ************/
//链接 https://webpack.js.org/guides/development/#webpack-dev-middleware
/*
renderFullPage函数,渲染完整的首屏可视页面(这个页面渲染完毕后将被发送到客户端)
第一个参数是被转成字符串的APP,要将其插入入口HMTL文件中
第二个参数是初始化的state,将其放入window对象中以便在发送到客户端后能通过window.__INITIAL_STATE__取用
*/ const renderFullPage = (html, preloadState) => {
return `<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>React App</title>
</head>
<body>
<div id="root">${html}</div>
<script>window.__INITIAL_STATE__ =${JSON.stringify(preloadState)}</script>
<script src="/static/bundle.js"></script>
</body>
</html>`
} const handleRender = (req, res) => {
// 初始化store,有两个作用:1.放入Provider的store属性中 2. 通过store.getState()获取初始化的state
const store = createStore()
// 将APP转成字符串
const html = ReactDOMServer.renderToString(
<Provider store={store}>
<App />
</Provider>
)
// 取得初始化的state
const preloadState = store.getState()
// 将渲染完整的首屏可视页面(字符串)发送到客户端显示
res.send(renderFullPage(html, preloadState))
} // 注册中间件函数,每当从客户端接收到请求的时候,运行handleRender函数
app.use(handleRender) // 监听3000端口
app.listen(3000, (error) => {
if (error) {
console.error(error)
}
})
// 确保在node环境下能编译es6(es2015)和JSX(react)的语法
require('babel-core/register')({
presets: ['es2015', 'react']
})
require('./server')
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import createStore from '../common/store'
import App from '../common/container' // 取得服务端发送过来的初始化state
const initialState = window.__INITIAL_STATE__
// 初始化store
const store = createStore(initialState)
// reactDOM渲染
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)

如何理解两个渲染过程?(ReactDOMServer.renderToString和 reactDOM.render的联系)

为什么要把state(redux)从服务端传到客户端?
解决服务端渲染代码中的“痛点”
在node环境运行ES6语法和JSX语法——babel-core/register的使用
require('babel-core/register')({
presets: ['es2015', 'react']
})
使发送到客户端的页面能访问打包后的bundle.js—— webpack.output.publicPath的使用
output:{
filename:'bundle.js',
path:path.join(__dirname,'dist'),
publicPath: '/static'
}
var webpackConfig = require('../../webpack.config.js');
// 省略其他内容
app.use(webpackDevMiddleware(compiler, {
publicPath:webpackConfig.output.publicPath // Same as `output.publicPath` in most cases.
}));
参考资料:文章标题,作者和链接(按先后顺序)
【redux】详解react/redux的服务端渲染:页面性能与SEO的更多相关文章
- vuejs服务端渲染更好的SEO,SSR完全指南Nuxt.js静态站生成器
vuejs服务端渲染更好的SEO,SSR完全指南Nuxt.js静态站生成器SSR 完全指南https://cn.vuejs.org/v2/guide/ssr.html在 2.3 发布后我们发布了一份完 ...
- 详解react/redux的服务端渲染:页面性能与SEO
亟待解决的疑问 为什么服务端渲染首屏渲染快?(对比客户端首屏渲染) react客户端渲染的一大痛点就是首屏渲染速度慢问题,因为react是一个单页面应用,大多数的资源需要在首次渲染前就加载 ...
- React(0.13) 服务端渲染的两个函数
1.React.renderToString 函数, 参数是组件,返回一个字符串 <!DOCTYPE html> <html> <head> <title& ...
- react+laravel与服务端渲染的几点思考
一.前后端完全分离 1.用React.js做MVC中的V,剩下的交给Laravel 2.Laravel用来做API接口开发. 3.好处:实现了前后端开发的分离,从而加快前后端开发效率.另外若是多端的如 ...
- Asp.Net MVC 模型验证详解-实现客户端、服务端双重验证
概要 在asp.net webform开发中经常会对用户提交输入的信息进行校验,一般为了安全起见大家都会在客户端进行Javascript(利于交互).服务端双重校验(安全).书写校验代码是一个繁琐的过 ...
- 解析Nuxt.js Vue服务端渲染摸索
本篇文章主要介绍了详解Nuxt.js Vue服务端渲染摸索,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. Nuxt.js 十分简单易用.一个简单 ...
- 教你如何在React及Redux项目中进行服务端渲染
服务端渲染(SSR: Server Side Rendering)在React项目中有着广泛的应用场景 基于React虚拟DOM的特性,在浏览器端和服务端我们可以实现同构(可以使用同一份代码来实现多端 ...
- react服务端渲染框架
客户端渲染 加载一个空的html页面,然后请求一个打包的js文件,然后再客户端执行这个js文件 动态生成html内容然后插入到DOM元素上,在源代码查询中也只能看到空的html文档 没有任何其他内容 ...
- 6.前端基于react,后端基于.net core2.0的开发之路(6) 服务端渲染(SSR)
0.源码地址 https://gitee.com/teambp/ScaffoldClient 这个地址下载对应源码. 1.服务端渲染是啥? 就是在服务器进行页面渲染(废话),当页面展示后,显示的就是 ...
随机推荐
- java 基础 ----- Arrays 工具类
----- Arrays 工具类是一个比较方便的类 常用的方法 也可以通过jdk文档进行查看 右侧有偶 对一些比较常用的方法进行演示 直接放在main方法中进行测试 ---- equ ...
- jmeter在几个固定的字符串中,随机取其中之一的方法
在测试过程中遇到上送字段必需是几个固定值中的一个, 使用读取文件中几个固定值,然后随机在这几个固定值中选择的办法解决问题 __CSVRead() CSV file to get values from ...
- go的包下载失败解决方案
包被墙的方案 1 翻啊的墙 2 gopm 3 https://github.com/golang/net 4 使用国内网站打包 5 export GOPROXY=https://goproxy.io
- NC 63凭证辅助相关表
1:通过公司主键(pk_org)在AccChartVO(表:bd_accchart)找:pk_accchart 2:通过科目编码和pk_accchart在AccAsoaVO(表:bd_accasoa) ...
- 如何在OneNote for Mac 中插入文件附件?
OneNote 2016 Mac是一款非常方便的云笔记软件,可以随时记录您稍纵即逝的创意,灵感和发现,发挥您的潜能,简化你的生活和工作.有用户反应如何在OneNote for Mac 中插入文件附件呢 ...
- web安全之机器学习入门——3.2 决策树与随机森林
目录 简介 决策树简单用法 决策树检测P0P3爆破 决策树检测FTP爆破 随机森林检测FTP爆破 简介 决策树和随机森林算法是最常见的分类算法: 决策树,判断的逻辑很多时候和人的思维非常接近. 随机森 ...
- Finance公式说明
公式说明 代码 说明 Y 期末余额 JY 期末借方余额 DY 期末贷方余额 C 期初余额 JC 期初借方余额 DC 期初贷方余额 SY 本期实际发生额 SL 利润表本年实际发生额 SY 期末余额 SJ ...
- Finance财务软件帮助
我们在凭证录入的时候可以使用这些快捷键增加效率: 单元格 快捷键 功能 摘要 F7 弹出摘要选择框 科目 F7 弹出科目选择框 科目 F8 弹出扩展字段编辑界面 金额 Esc/小键盘- 清空 金额 = ...
- AX_CreateAndPostSales
static void CreateAndPostSales(Args _args) { List il = new List(Types::Record); SalesTable localSale ...
- Linux---基础指令(一)
https://www.linuxprobe.com/chapter-02.html (Linux就要这么学) 一.执行查看帮助命令 date:date命令用于显示及设置系统的时间或日期,格式为“d ...