今天开会,同事突然说,我们的项目首屏渲染时间太久,引起客诉了。怎么办呢,需要把项目从客户端渲染转为服务端渲染,也就是SSR,大家一起想想研究一下怎么改才好。
我:啊?
于是,打开Google,郑重地打出了三个字母+三个汉字:什么是SSR
把学习笔记记录在这。

————————
最后我们使用了next框架改。

——————————

什么是SSR

  • 先看:https://juejin.cn/post/6844904017487724557
  • 讲的也很详细,带React样例(我的重点参考):https://juejin.cn/post/6844903881390964744
  • Vue项目的SSR demo,但是里面有很多内容是共通的:https://github.com/yacan8/blog/issues/30
  • 补充个,服务端渲染也是分不同渲染方式的:https://zhuanlan.zhihu.com/p/341229054
    (像是官网等等数据不流通且不针对用户特殊处理的就可以使用SSG静态渲染)

如果要动手将一个单页面React应用转为SSR项目应该怎么做?

  • react ssr 服务端渲染入门
    https://juejin.cn/post/6935621064517451812
  • https://cnodejs.org/topic/5b9ce0298f5b0c1c59ea0e5b

大佬们的demo大概是以下几个流程,我先以自己理解写点笔记,然后尝试着写一个简单demo出来。

1、传输静态页面。

使用ReactDOMServer.renderToString 或者ReactDOMServer.renderToNodeStream 方法,将写的JSX解析为html字符串。

2、同构。

什么是同构呢?因为服务端和客户端要获得相同的默认state数据,在初始化的时候,服务端获取了一遍数据,然后注入state,传入客户端,客户端就不用重新请求一遍了(还可能造成数据不统一),服务端和客户端的数据保持一致,就是同构。
同构和数据、js请求、路由都有关,所以我这认为同构是交互层面的。

因为我们项目原本就定了使用egg,所以我得在egg的基础上考虑SSR。
首先npm init egg --type=simple 创建一个空的egg项目。
参考
别人写好可使用的egg-react-ssr 脚手架。https://github.com/zhangyuang/egg-react-ssr
其他demo 参考:https://github.com/yjdjiayou/react-ssr-demo (从头创建)

1、node服务器返回静态HTML页面。
对Egg框架稍微了解一点之后,我需要把返回HTML的代码 放在controller/home里。
也就是说,首先建立一个写react代码的文件夹(我建了page文件夹),然后再在node服务器里引用react页面代码,这样才能做到服务器解析html渲染。
然后,因为我们写的都是JSX片段(虚拟DOM),肯定是无法渲染的,第二步就是将它在node端转换为html代码返回给浏览器。

// 新建一个page文件夹, /page/index.jsimport React from 'react'export default function HTML(props){return <div><p>SSR</p><p>纯静态渲染</p>
</div>
}

const { renderToString } = require('react-dom/server');renderToString就是react中提供用于编译虚拟DOM的方法,它可以将react的虚拟dom转为真实的html节点。我们使用这个方法帮我们处理一下引入的页面。

// /app/controller/home.js'use strict';const Controller = require('egg').Controller;
import Home from '../../page/index';
import { renderToString } from 'react-dom/server';class HomeController extends Controller {async index() {const { ctx } = this;ctx.type = 'text/html'ctx.status = 200;const content = renderToString(<Home />);ctx.body = `<html><head><title>ssr</title></head><body><div id="root">${content}</div></body></html>`;}
}module.exports = HomeController;

看上去好像和资料参考里的一模一样,肯定没问题了!自信满满的我在这个项目终端里打下npm start!
嗯!不出意料,根本启不起来!是因为import无法解析,egg中暂时不支持esm,所以需要把引入方式改成cmd模式,但是egg项目中使用esm没关系,我们的page页面里用cmd根本不好写,所以思来想去,难不成还是得用babel?
查询了一些资料,不少项目都是将node端和客户端代码分别打包,虽然我还是挺懵的,但是搞不懂的话就写bug试一下吧。
于是自信满满(x)的我又在百度打下了几个字:怎么使用webpack babel

总之咱们的pages文件夹下肯定是用webpack编译一下了。
这部分的参考:https://blog.csdn.net/u012443286/article/details/79577545
webpack文件内容参考https://github.com/yjdjiayou/react-ssr-demo
npm i webpack babel-loader babel-core babel-preset-env -D
npm i @babel/core @babel/preset-env @babel/preset-react @babel/plugin-proposal-class-properties -D

新增三个文件

// /config/webpack.base.js'use strict';// const path = require('path');
module.exports = {mode: 'development',module: {rules: [{test: /\.js$/,loader: 'babel-loader',exclude: /node_modules/,options: {presets: ['@babel/preset-env','@babel/preset-react',],plugins: ['@babel/plugin-proposal-class-properties',],},},],},
};
// /config/webpack.client'use strict';const path = require('path');
const merge = require('webpack-merge');
const base = require('./webpack.base');module.exports = merge(base, {entry: './src/client/index.js',output: {path: path.resolve('public'),filename: 'client.js',},module: {rules: [{test: /\.css$/,use: ['style-loader',{loader: 'css-loader',options: {modules: true,},},],},],},
});
// config/webpack.server'use strict';const path = require('path');
const nodeExternal = require('webpack-node-externals');
const merge = require('webpack-merge');
const base = require('./webpack.base');module.exports = merge(base, {// 注意这个值target: 'node',entry: './src/server/index.js',output: {path: path.resolve('build'),filename: 'server.js',},externals: [ nodeExternal() ],module: {rules: [{test: /\.css$/,use: [// 服务端渲染不能用 style-loader,因为 node 没有 document 对象,无法插入 style 标签// 服务端本来就不能渲染 dom,只是提供 html/css/js 代码给浏览器,交给浏览器去渲染// 服务端返回的 html 源码里,没有 style 标签// 而在浏览器中的 html 源码里,有 style 标签,是通过 js 插入进去的'isomorphic-style-loader',{loader: 'css-loader',options: {modules: true,},},],},],},
});

SSR项目学习和使用相关推荐

  1. PHP项目学习——控件

    主要是在项目学习中总结的一些东西 动态效果 flashbar滚动条,增加动态效果,直接嵌入html中 <!--flash滚动条--><object classid="cls ...

  2. 如何自学python到做项目-总算明白如何通过项目学习python

    在学习完Python的基础知识之后,有很多朋友为自己接下来要干什么感到迷茫.不知道应该通过什么样的项目来锻炼自己编程水平和思维能力.接下来我就给大家说几个适合Python的新手项目和练手项目,Pyth ...

  3. 延大计算机文化基础课程作业,基于项目学习的大学《计算机文化基础课》教学设计...

    摘要: 从大学教育看,计算机文化已经愈来愈多地融入了各专业科研和专业课的教学过程之中.计算机教学已成为素质教育的必要组成部分,良好的信息素养是当代大学生可持续发展的重要基础平台.大学计算机文化基础课程 ...

  4. TheBeerHouse 网站项目学习笔记(5)---架构设计

    前述讨论:    TheBeerHouse 网站项目学习笔记(1)----换肤技术                     TheBeerHouse 网站项目学习笔记(2)----个性化管理      ...

  5. 引入dubbo依赖的版本是多少_Dubbo 项目学习(四) 接口抽取以及依赖版本统一

    引言 前面的系列项目中,我们会发现有个接口是一样的,我们需要单独抽取出来,统一维护,这样可以更加高效的处理项目.同时,两个项目的maven依赖包也可以统一维护,这样有助于项目在多人协作的同时,保证项目 ...

  6. 01-Flutter移动电商实战-项目学习记录

    01-Flutter移动电商实战-项目学习记录 一直想系统性的学习一下 Flutter,正好看到该课程<Flutter移动电商实战>的百度云资源,共 69 课时,由于怕自己坚持不下去(经常 ...

  7. 项目学习 - 收藏集 - 掘金

    一款开源的视频直播项目 --EvilsLive - Android - 掘金 项目介绍 EvilsLive 是一个视频直播件开发工具包(SDK), 目前只支持 Android, 主要负责视频直播的采集 ...

  8. python3实战练手项目_Python0基础练手项目有哪些值得推荐?附实战项目+学习图谱...

    原标题:Python 0基础练手项目,有哪些值得推荐?附实战项目+学习图谱 刚学Python的时候,因为豆瓣帖子老沉,就写了一个顶帖脚本.就是用这个脚本,给自己的帖子顶了两年,在小组里追到了现在的女朋 ...

  9. VUE项目学习(三):win10版nginx部署vue项目

    VUE项目学习(三):win10版nginx部署vue项目 niginx的安装和启停操作参照博客:https://blog.csdn.net/qq_26666947/article/details/1 ...

最新文章

  1. 设计模式----组合模式UML和实现代码
  2. 一句话总结LLE(流形学习)
  3. echo * 和ls *之间的区别?
  4. Mybatis-plugins分页助手实现查询数据分页
  5. 关于strlwr,strupr等函数在此作用域中尚未声明的问题
  6. 这款耳机堪比千元级的AirPods
  7. mengento 数据库模型
  8. [编写高质量代码:改善java程序的151个建议]后记
  9. Linux基础(十一)--Linux文件查找命令Find详解
  10. node.js入门及安装
  11. 一道装呀(状压)DP
  12. 矢量字体合并《注意事项》
  13. Android启动过程研究(二:AIL描述的init.rc)
  14. angular中的变更检测机制
  15. Flink SQL CDC 13 条生产实践经验
  16. springboot+hutool批量生成二维码压缩导出
  17. 【数据库】MySQL 加锁处理分析
  18. sql将日期格式化特定的字符串格式
  19. settimeout一定要清除么?
  20. 技术资料收集 技术大牛及网站推荐 待研究方向

热门文章

  1. 南瑞通讯管理机测试软件,国电南瑞NSC2200E 通讯管理机
  2. CMD命令行中以管理员权限启动应用程序实现方法
  3. mysql创建角色集_mysql8之新增角色
  4. Qt之QTcpServer/QTcpSocket简单收发信息(1)
  5. 王永庆:从借200元钱起家
  6. 爬取网易财经全部A股上市公司年报
  7. 第三方服务 “TOP10”Java 后端开发常用的
  8. RSA(python)
  9. kubeadm部署kubernetes高可用(三主三从)
  10. 为什么我说Rust是靠谱的编程语言