手把手从头开始教你,彻底理解服务端渲染原理( 五 )


 

手把手从头开始教你,彻底理解服务端渲染原理

文章插图
 
数据已经挂载到了服务端返回的HTML代码中 。那这就说明服务端和客户端的store不同步的问题 。
 
其实也很好理解 。当服务端拿到store并获取数据后,客户端的js代码又执行一遍,在客户端代码执行的时候又创建了一个空的store,两个store的数据不能同步 。
那如何才能让这两个store的数据同步变化呢?
首先,在服务端获取获取之后,在返回的html代码中加入这样一个script标签:
<script>window.context = {state: ${JSON.stringify(store.getState())}}</script>复制代码这叫做数据的“注水”操作,即把服务端的store数据注入到window全局环境中 。接下来是“脱水”处理,换句话说也就是把window上绑定的数据给到客户端的store,可以在客户端store产生的源头进行,即在全局的store/index.js中进行 。
//store/index.jsimport {createStore, applyMiddleware, combineReducers} from 'redux';import thunk from 'redux-thunk';import { reducer as homeReducer } from '../containers/Home/store';const reducer = combineReducers({home: homeReducer})//服务端的store创建函数export const getStore = () => {return createStore(reducer, applyMiddleware(thunk));}//客户端的store创建函数export const getClientStore = () => {const defaultState = window.context ? window.context.state : {};return createStore(reducer, defaultState, applyMiddleware(thunk));}复制代码至此,数据的脱水和注水操作完成 。但是还是有一些瑕疵,其实当服务端获取数据之后,客户端并不需要再发送Ajax请求了,而客户端的React代码仍然存在这样的浪费性能的代码 。怎么办呢?
还是在Home组件中,做如下的修改:
componentDidMount() {//判断当前的数据是否已经从服务端获取//要知道,如果是首次渲染的时候就渲染了这个组件,则不会重复发请求//若首次渲染页面的时候未将这个组件渲染出来,则一定要执行异步请求的代码//这两种情况对于同一组件是都是有可能发生的if (!this.props.list.length) {this.props.getHomeList()}}复制代码一路做下来,异步数据的服务端渲染还是比较复杂的,但是难度并不是很大,需要耐心地理清思路 。
至此一个比较完整的SSR框架就搭建的差不多了,但是还有一些内容需要补充,之后会继续更新的 。加油吧!
part5: node作中间层及请求代码优化一、为什么要引入node中间层?其实任何技术都是与它的应用场景息息相关的 。这里我们反复谈的SSR,其实不到万不得已我们是用不着它的,SSR所解决的最大的痛点在于SEO,但它同时带来了更昂贵的成本 。不仅因为服务端渲染需要更加复杂的处理逻辑,还因为同构的过程需要服务端和客户端都执行一遍代码,这虽然对于客户端并没有什么大碍,但对于服务端却是巨大的压力,因为数量庞大的访问量,对于每一次访问都要另外在服务器端执行一遍代码进行计算和编译,大大地消耗了服务器端的性能,成本随之增加 。如果访问量足够大的时候,以前不用SSR的时候一台服务器能够承受的压力现在或许要增加到10台才能抗住 。痛点在于SEO,但如果实际上对SEO要求并不高的时候,那使用SSR就大可不必了 。
那同样地,为什么要引入node作为中间层呢?它是处在哪两者的中间?又是解决了什么场景下的问题?
在不用中间层的前后端分离开发模式下,前端一般直接请求后端的接口 。但真实场景下,后端所给的数据格式并不是前端想要的,但处于性能原因或者其他的因素接口格式不能更改,这时候需要在前端做一些额外的数据处理操作 。前端来操作数据本身无可厚非,但是当数据量变得庞大起来,那么在客户端就是产生巨大的性能损耗,甚至影响到用户体验 。在这个时候,node中间层的概念便应运而生 。
它最终解决的前后端协作的问题 。
一般的中间层工作流是这样的:前端每次发送请求都是去请求node层的接口,然后node对于相应的前端请求做转发,用node去请求真正的后端接口获取数据,获取后再由node层做对应的数据计算等处理操作,然后返回给前端 。这就相当于让node层替前端接管了对数据的操作 。
 
手把手从头开始教你,彻底理解服务端渲染原理

文章插图
 
 
二、SSR框架中引入中间层在之前搭建的SSR框架中,服务端和客户端请求利用的是同一套请求后端接口的代码,但这是不科学的 。


推荐阅读