zoukankan      html  css  js  c++  java
  • 6.前端基于react,后端基于.net core2.0的开发之路(6) 服务端渲染(SSR)

    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.结尾

    代码真的很少很简单,所以并不难。

    大家对着项目看看,应该就明白了

     
     
  • 相关阅读:
    【C/C++】最长公共子序列(LCS)/动态规划
    【C/C++】vector 动态二维数组
    【C/C++】string的长度
    【C/C++】最长不下降子序列/动态规划
    【C/C++】最大连续子序列和/动态规划
    【C/C++】输入:连续输入,以逗号隔开
    【C/C++】链表/ListNode/数据结构
    【Matlab】abs不支持复整数
    获取正在运行的服务
    从源码的角度分析Volley加载数据的过程
  • 原文地址:https://www.cnblogs.com/Ambre/p/8251903.html
Copyright © 2011-2022 走看看