【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.服务端渲染是啥? 就是在服务器进行页面渲染(废话),当页面展示后,显示的就是 ...
随机推荐
- 摘选改善Python程序的91个建议2
62.metaclass stackflow 中文翻译 63.Python对象协议 https://zhuanlan.zhihu.com/p/26760180 ...
- php 微信自定义分享接口
<?php class JSSDK { private $appId; private $appSecret; public function __construct($appId, $appS ...
- nio实现原理
nio是事件驱动,当soket有消息过来时才开启线程,bio每当有连接时,就开启一个线程,长连接的话,就有太多的空闲连接占用线程内存 nio是非阻塞长连接 ServerSocketChannel:饭店 ...
- scrapy 爬取小说
QiushuSpider # -*- coding: utf-8 -*- import scrapy import time from qiushu.items import QiushuItem c ...
- Eureka的服务注册与发现概念(三)
一.Eureka介绍 Netflix在设计Eureka时遵守的AP原则.Eureka是Netflix的一个子模块,也是核心模块之一.Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层 ...
- 20175325 《JAVA程序设计》实验二《JAVA开发环境的熟悉》实验报告
20175325 <JAVA程序设计>实验二<JAVA开发环境的熟悉>实验报告 一.实验报告封面 课程:Java程序设计 班级:1753班 姓名:石淦铭 学号:20175325 ...
- HTTP之请求消息Request
客户端发送一个HTTP请求到服务器的请求消息包括以下格式: 请求行(request line).请求头部(header).空行和请求数据四个部分组成. 请求行以一个方法符号开头,以空格分开,后面跟着请 ...
- [原创]networkx 画中文节点
一直想分享一些自己遇到的坑,但确实很多时候走的太快 很多想做的事情会被快节奏的生活冲淡, 在公司做事反而比学校还自在, 因为是悠闲的实习期... 几点小建议写在前头--xdj: 遇到问题,大多数人首先 ...
- Selenium+PyCharm环境搭建
一.首先安装python并配置好环境变量 二.安装selenium 安装文件夹在安装的python文件夹下,例:D:\Program\python\Lib\site-packages\selenium ...
- 关于分布式事务,XA协议的学习笔记
XA分布式事务协议,包含二阶段提交(2PC),三阶段提交(3PC)两种实现. 1.二阶段提交方案:强一致性 事务的发起者称协调者,事务的执行者称参与者. 处理流程: 1.准备阶段 事务协调者,向所有事 ...