React服务器渲染最佳实践
源码地址:https://github.com/skyFi/dva-starter
React服务器渲染最佳实践
dva-starter
完美使用 dva react react-router,最好用的ssr脚手架,服务器渲染最佳实践
欢迎 Fork ,Issue 交流各种想法
- 努力在最佳的路上,不断完善,建议star或watch.
- 有想法就Fork, Pull requests ,我很耐 操.
Usage
安装redis
$ brew install redis
启动redis
$ brew services start redis
准备配置文件
- 将config.example.js拷贝一份config.js并修改为你想要的配置
- 共两个地方
运行
'production': $ npm run start
'development': $ npm run dev
服务器渲染需要的initData
对于服务器渲染需要获取的数据,放置的model中的initData中,结构和effects一样,也一样可以在页面中像调用effects一样调用,你所需要关心的仅仅是哪些数据需要首屏出现,把它从effects中移到initData中即可,其他的你都不需要关心了,是不是很爽,哇哈哈
export default ModelHelper({
namespace: 'user',
state: [
{
list: undefined,
}
],
reducers: {
list(state, { list }) {
return { ...state, list };
},
},
effects: {
*fetchTodoList(action, { call, put }) {
const res = yield call(fetchTodoList);
if (res) {
yield put({
type: 'list',
list: res
});
} else {
throw new Error(`Init data Error: fetchTodoList.`);
}
},
},
initData: {
*fetchAnotherList({}, { call, put }) {
const res = yield call(fetchAnotherList);
if (res) {
yield put({
type: 'list',
list: res
});
} else {
throw new Error(`Init data Error: fetchAnotherList.`);
}
},
},
})
魔法全局变量initialState的消失
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="/index.css" />
</head>
<body>
<div id="root">
<div>
<div data-reactroot="" data-reactid="1" data-react-checksum="-35862160"><div data-reactid="2"><h1 data-reactid="3"><!-- react-text: 4 -->App _ <!-- /react-text --><!-- react-text: 5 --><!-- /react-text --></h1><h3 data-reactid="6">About</h3><h3 data-reactid="7">点我试试</h3><h2 class="title" data-reactid="8">User</h2><div data-reactid="9"><!-- react-text: 10 -->- <!-- /react-text --><!-- react-text: 11 -->周静<!-- /react-text --></div><div data-reactid="12"><!-- react-text: 13 -->- <!-- /react-text --><!-- react-text: 14 -->侯军<!-- /react-text --></div><div data-reactid="15"><!-- react-text: 16 -->- <!-- /react-text --><!-- react-text: 17 -->郭超<!-- /react-text --></div><div data-reactid="18"><!-- react-text: 19 -->- <!-- /react-text --><!-- react-text: 20 -->乔涛<!-- /react-text --></div><div data-reactid="21"><!-- react-text: 22 -->- <!-- /react-text --><!-- react-text: 23 -->杨超<!-- /react-text --></div><div data-reactid="24"><!-- react-text: 25 -->- <!-- /react-text --><!-- react-text: 26 -->万娟<!-- /react-text --></div><div data-reactid="27"><!-- react-text: 28 -->- <!-- /react-text --><!-- react-text: 29 -->何超<!-- /react-text --></div><div data-reactid="30"><!-- react-text: 31 -->- <!-- /react-text --><!-- react-text: 32 -->戴秀兰<!-- /react-text --></div><div data-reactid="33"><!-- react-text: 34 -->- <!-- /react-text --><!-- react-text: 35 -->孙秀英<!-- /react-text --></div><div data-reactid="36"><!-- react-text: 37 -->- <!-- /react-text --><!-- react-text: 38 -->邹超<!-- /react-text --></div><div data-reactid="39"><!-- react-text: 40 -->- <!-- /react-text --><!-- react-text: 41 -->苏刚<!-- /react-text --></div><div data-reactid="42"><!-- react-text: 43 -->- <!-- /react-text --><!-- react-text: 44 -->毛刚<!-- /react-text --></div><div data-reactid="45"><!-- react-text: 46 -->- <!-- /react-text --><!-- react-text: 47 -->萧丽<!-- /react-text --></div><div data-reactid="48"><!-- react-text: 49 -->- <!-- /react-text --><!-- react-text: 50 -->胡勇<!-- /react-text --></div><div data-reactid="51"><!-- react-text: 52 -->- <!-- /react-text --><!-- react-text: 53 -->毛刚<!-- /react-text --></div><div data-reactid="54"><!-- react-text: 55 -->- <!-- /react-text --><!-- react-text: 56 -->贺强<!-- /react-text --></div></div></div>
</div>
</div>
<script type="text/javascript" src="/states/YT50C6TStrTsitaHF0gwkxpyslhAYJAZ1489673610988.js"></script>
<script src="/index.js"></script>
</body>
</html>
最初版本采用了一个全局变量initialState来将服务器渲染时获得的初始化states同步到客户端初始化的states,这个方法有个弊端,
第一,暴漏个全局的变量,不爽;
第二,不够优雅;
第三,使得html页面拥有大段大段的script,这会降低你的网站在百度的权重!。
所以,这里将states放到了一个redis中缓存,避免了一些问题,但,伟大的同性交流平台啊,这一定有更好的解决办法,如果有,那你一定要告诉我,翘首期盼之!!
目前最佳方案:
- 缓存住准备好的初始化states
module.exports.set = function *(stateString) {
const key = randomstring.generate() + Date.now();
yield cache.setexAsync(`${cache.prefix}:state:${key}`, EXPIRE, stateString);
return key;
};
- 页面加载
<script type="text/javascript" src="/states/${stateKey}.js"></script>
- 路由截取
app.use('/states/(:key).js', stateServe);
- 页面同步states
const app = createApp({
history: browserHistory,
initialState: JSON.parse(window.states),
}, { router, models });
- 删除states
delete window.states;
最后,如果你有更好的解决方案,请一定要告诉我,不甚感激!
React服务器渲染最佳实践的更多相关文章
- 腾讯优测优分享 | 探索react native首屏渲染最佳实践
腾讯优测是专业的移动云测试平台,旗下的优分享不定时提供大量移动研发及测试相关的干货~ 此文主要与以下内容相关,希望对大家有帮助. react native给了我们使用javascript开发原生app ...
- 探索react native首屏渲染最佳实践
文 / 腾讯 龚麒 0.前言 react native给了我们使用javascript开发原生app的能力,在使用react native完成兴趣部落安卓端发现tab改造后,我们开始对由react n ...
- React 服务器渲染原理解析与实践
第1章 服务器端渲染基础本章主要讲解客户端与服务器端渲染的概念,分析客户端渲染和服务器端渲染的利弊,带大家对服务器端渲染有一个粗浅认识. 1-1 课程导学1-2 什么是服务器端渲染1-3 什么是客户端 ...
- 我们编写 React 组件的最佳实践
刚接触 React 的时候,在一个又一个的教程上面看到很多种编写组件的方法,尽管那时候 React 框架已经相当成熟,但是并没有一个固定的规则去规范我们去写代码. 在过去的一年里,我们在不断的完善我们 ...
- 《React设计模式与最佳实践》笔记
书里的demo都是15.3.2以下版本的,有些demo用最新的react 16.x版本会报错,安装包的时候记得改一下版本 第一章 React 基础 命令式编程描述代码如何工作,而声明式编程则表明想 ...
- React 代码共享最佳实践方式
任何一个项目发展到一定复杂性的时候,必然会面临逻辑复用的问题.在React中实现逻辑复用通常有以下几种方式:Mixin.高阶组件(HOC).修饰器(decorator).Render Props.Ho ...
- 编写React组件的最佳实践
此文翻译自这里. 当我刚开始写React的时候,我看过很多写组件的方法.一百篇教程就有一百种写法.虽然React本身已经成熟了,但是如何使用它似乎还没有一个"正确"的方法.所以我( ...
- React项目的最佳实践
项目代码 从零开始简书项目 从我第一次接触vue这个框架已经过了快一年的时间,陪伴我从前端小白到前端工程师,前端时间也是使用了 ts+vue这样的组合写代码,明显感觉vue与ts似乎没有产生比较好 ...
- react性能优化最佳实践
1.PureComponent 的使用场景 PureComponent 和 Component 的区别是,PureComponent 自带 shouldComponentUpdate 生命周期函数,会 ...
随机推荐
- Spring RESTful + Redis全注解实现恶意登录保护机制
好久没更博了... 最近看了个真正全注解实现的 SpringMVC 博客,感觉很不错,终于可以彻底丢弃 web.xml 了.其实这玩意也是老东西了,丢弃 web.xml,是基于 5.6年前发布的 Se ...
- JS邮箱验证-正则验证
<form act="">输入:<input type="text" name="qc" id="qc" ...
- 强大的健身软件——Keep
Keep是一款具有社交属性的健身工具类产品.用户可利用碎片化的时间,随时随地选择适合自己的视频健身课程,进行真人同步训练.完成后还可以"打卡"晒成就. 你可根据器械.部位.难度 ...
- 2015: [Usaco2010 Feb]Chocolate Giving
2015: [Usaco2010 Feb]Chocolate Giving Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 269 Solved: 1 ...
- Java容器源码解析之——ArrayList
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...
- ReactJS React+Redux+Router+antDesign通用高效率开发模板,夜间模式为例
工作比较忙,一直没有时间总结下最近学习的一些东西,为了方便前端开发,我使用React+Redux+Router+antDesign总结了一个通用的模板,这个技术栈在前端开发者中是非常常见的. 总的来说 ...
- commonJS的核心思想
服务器端的 Node.js 遵循 CommonJS规范,该规范的核心思想是允许模块通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或 module.exports 来 ...
- Java中Comparable和Comparator你知多少?
前言: 我喜欢这种遨游在Java的世界里,精心研究学习新鲜事物的感觉,即便再小再细再微不足道的东西,也让我乐此不疲,同时我也更愿意将我所会的东西分享出来供大家学习以及方便自己日后回顾.好了,闲话不多说 ...
- (15)IO流之File
File类用封装了一个文件夹或者文件的所有属性. File类的构造方法: File(String pathname) 指定文件或者文件夹的路径创建一个File文件 File(File parent, ...
- vueJS 获取后台数据 绑定data
//vue 环境安装http://blog.csdn.net/u013182762/article/details/53021374 一开始使用安装环境配置一些东西 ,后来发现太麻烦了 . 直接CD ...