详解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.
}));
参考资料:文章标题,作者和链接(按先后顺序)
详解react/redux的服务端渲染:页面性能与SEO的更多相关文章
- 【redux】详解react/redux的服务端渲染:页面性能与SEO
亟待解决的疑问 为什么服务端渲染首屏渲染快?(对比客户端首屏渲染) react客户端渲染的一大痛点就是首屏渲染速度慢问题,因为react是一个单页面应用,大多数的资源需要在首次渲染前就加载 ...
- vuejs服务端渲染更好的SEO,SSR完全指南Nuxt.js静态站生成器
vuejs服务端渲染更好的SEO,SSR完全指南Nuxt.js静态站生成器SSR 完全指南https://cn.vuejs.org/v2/guide/ssr.html在 2.3 发布后我们发布了一份完 ...
- 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.服务端渲染是啥? 就是在服务器进行页面渲染(废话),当页面展示后,显示的就是 ...
随机推荐
- centos mysql5.7 二进制包安装
此种方式安装非常简单 cd /usr/local 下载安装包wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.17-linux- ...
- java面向对象--类加载器及Class对象
类加载器 jvm 和 类的关系 当调用 java命令运行一个java程序时,会启动一个java虚拟机进程.同一个jvm的所有线程.所有变量都处于同一个进程里,都使用该jvm进程的内存区. jvm进程终 ...
- Two Sum 2015年6月8日
Given an array of integers, find two numbers such that they add up to a specific target number. The ...
- 使用 CKEditor 上传图片, 粘贴屏幕截图
之前写过wangEditor,那真是好用,文档也清晰,半天就搞定了,无奈没有对应license,只好选择别的. 外语一般,阅读理解都靠蒙.CKEditor官方文档看的我云里雾里,国内的博客比较少,经过 ...
- java 上传1(使用java组件fileupload)
使用fileupload要添加以下包
- php微信支付问题之 cURL error 60: SSL certificate: unable to get local issuer certificate
cacert.pem(点击下载) 解决办法:比如我本地安装的是wamp,将cacert.pem文件放在这个文件夹下面D:\wamp\bin\php\php5.5.12\ext 如果安装的phpStud ...
- 分布式版本控制git常见问题之gitignore冲突
所见即所得,建议大家用可视化的SourceTree专为git打造的,非常好用,废话不多说了. 原因是有人提交了.gitignore里面的内容,所以和本地的不一样,这样就有问题,那么pull都不可以,所 ...
- 什么样的PPT能助你成为一个优秀的演讲者——程序员的演讲之道
欢迎访问我的个人博客,原文链接:http://wensibo.top/2017/05/28/speaker/ ,未经允许不得转载! 前言 今天是端午节假期的第一天,在这里祝大家假期快乐,不过像我这种渣 ...
- ReactNative学习之Html基本标签使用
前言: 前面简单学习了html简单标签的使用,今天学习一下其他的标签的使用. HTML的超链接 1.)创建一个超链接 <div> <p> <a href="ht ...
- 网络安全——一图看懂HTTPS建立过程
关于网络安全加密的介绍可以看之前文章: 1. 网络安全--数据的加密与签名,RSA介绍 2. Base64编码.MD5.SHA1-SHA512.HMAC(SHA1-SHA512) 3. When I ...