0. 源码地址
https://gitee.com/teambp/ScaffoldClient 这个地址下载对应源码.
1. 服务端渲染是啥?
就是在服务器进行页面渲染(废话),当页面展示后,显示的就是最终的页面.最简单的识别方式,你页面上的所有东西,在右键 -> 查看源码后都可以看到 (如果实现 SEO 的话).
2. 服务端渲染的好处
1.SEO
2. 首屏体验更好
3. 整体 APP 的体验,因为是先缓存所有,再进行加载,没有额外的资源需要加载
3. 文章做到了那一步
首先,因为后台应用,所以并没有解决 SEO 的问题..
如果要解决 SEO 的问题,我的思路是,把需要 SEO 的页面跳转都用 window.location.href 跳转,然后把需要渲染的东西放到 initState 里,然后页面上读取 initState 进行页面组装,渲染,如果有兴趣,大家可以自己实现以下,这样基本可以实现 SEO.
然后,后台感觉非常的顺滑,因为所有页面控件都已经到 js 里面了,所以,跳转的时候,没有任何白屏,卡屏等等情况.这也是服务端渲染的优势.
其次,因为服务端渲染要用到 node,这样,你的所有请求都可以先拦截一下做下处理,然后转发过去.
node 层是一个非常好的,进行请求转发的层,可以避免很多问题.
最后,使用 Node 做服务端渲染可以更好的同构,这样客户端代码和渲染代码都在一个项目里,方便维护
4. 使用了啥
简单来说就是 Node,React-Router V2/3, Express.
如果大家想知道 V4 版本的这么实现...我先自己实现了后,再写一篇告诉大家.
5. 开始
就不重新开项目了,
大家去码云上: https://gitee.com/teambp/ScaffoldClient
把这个项目 Down 下来,照着文章看就行了
我也只是简略说下主要代码
第一个重要的地方,入口,也就是 webpack 的入口
打包的入口
第二个,node 层 express 注入 ssr 的拦截器
最关键的代码
重要的地方已经标红显示了
isomorphism - >CreateApp export
default
function createApp(opts, isServer) {
var nowOption = ({...createLoading({
effects: true,
}),
history: opts.history,
initialState: opts.initialState,
});
const app = dva(nowOption);
//加载模型
app.model(require('./models/authorities/user'));
if (isServer) {
//服务端渲染走
app.router(({
history,
renderProps
}) = >{
return < RouterContext {...renderProps
}
/>;
});
} else {
app.router(router);
}
return app;
}
server->server.js
import { match, RoutingContext, createMemoryHistory } from 'dva/router ';
import { renderToString } from 'react - dom / server '
import { routes } from '.. / isomorphism / router ';
import createApp from '.. / isomorphism / createApp ';
import config from '. / utils / config ';
import createLoading from 'dva - loading ';
export default function (req, res) {
match({
routes,
location: req.url,
}, (err, redirectLocation, renderProps) => {
if (err) {
res.status(500).end(`Internal Server Error ${err}`);
}
else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
const other = createApp({
history: createMemoryHistory(),
}, true);
const otherhtml = renderToString(other.start()({ renderProps }));
const loginuser = req.session.user || {};
const loginstate = req.session.user ? true : false;
res.end(renderFullPage(otherhtml, { staticServer: config.staticServer, sessionid: req.session.id, userinfo: loginuser, islogin: loginstate }));
} else {
res.status(404).send('Not found ');
}
});
}'
renderToString方法是react提供的,用于服务端的代码,也就是说,react本来就支持服务端渲染
createMemoryHistory 这个方法是指定路由所保存的位置,也就是实现服务端渲染的核心
当所有的js被打包,然后被一次性加载完毕,然后在首次打开页面的时候加载,请求到对应路由的时候,直接在加载好(内存中)的路由,直接渲染,
这样就完爆了跳转页面后,还需要先加载对应路由的资源文件,然后在渲染的速度.
最后写完,打开页面,右键->查看源码
的确是服务端渲染了.
而没有服务端渲染的,查看源码大概是这样
5. 结尾
代码真的很少很简单,所以并不难.
大家对着项目看看,应该就明白了
来源: https://www.cnblogs.com/Ambre/p/8251903.html