后端同事不理解为啥服务端渲染用 node 来开发?

289 阅读3分钟

这个问题本质上还是看现在的服务端渲染都要做哪些事情

背景

很早之前开发前端页面都是用 Java、Jsp 或者 PHP,那能否用 Java or PHP 结合 React 开发服务端代码呢?

先介绍下 CSR

页面的 HTML 渲染完全在客服端进行,参考下图

image.png

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="css/style.css">
</head>

<body>
    <div id="root"></div>
    <script src="js/react.js"></script>
    <script src="js/react-dom.js"></script>
    <script src="js/业务.js"></script>
    <script src="js/xxx业务.js"></script>
</body>

</html>

页面通过加载相应的 js, 上面的 app 节点,会被 react 或者 vue 来接管, 然后发请求要数据,渲染成 dom 节点,

前端目录结构大概如下,

  • components 存放组件,因为现在有了打包工具之后,都是模块化
  • pages 存放页面
    • pageA
      • index.js
      • style.css
      • service.js
      • ts 有可能有ts
  • utils 工具函数,包括请求
  • store 全局
  • assets 静态资源
  • main.js 主入口,

主入口一般是 React 路由,入口初始化代码

import App from './App';          
                                                               
ReactDOM.render(                  
    <React.StrictMode>                
         <App />                           
    </React.StrictMode>,              
    document.getElementById('root')   
);

CSR 部署

一般是需要 webpack 等打包工具进行打包, 通过一个入口文件,查找所有的依赖,最终打包出一个 dist, 这里都是 js 、css 图片等资源, 最终部署在 ng 服务上

CSR 路由控制

以前的服务端渲染路由都是服务器控制 而 CSR 路由能力是前端来实现 a 标签跳转,以及页面的销毁与渲染。 当访问某一个 CSR 页面时候,会先加载相关静态资源,然后根据路由, 跳转到对应页面,加载这个页面代码,并且会加载这个页面的子组件, 然后发送请求,页面和组件都可能发请求。

再来看下 SSR

图片也是来自掘金

image.png

image.png

从内容可见的时间上,SSRCSR更快。

以前的服务端渲染,都是一个 模板 + 相关数据来做,页面比较简单,可能一个两个接口就能搞定了。

类似如下,少量数据、简单的Html拼接,在服务的代码里面就拼好了,或者是一个 html 模板中拼完。

const http = require("http");
//模拟数据的获取
const fetchData = function () {
  return {
    list: [
      { name: "包子", num: 100 },
      { name: "饺子", num: 2000 },
      { name: "馒头", num: 10 },
    ],
  };
};
//数据转换为 html 内容
const dataToHtml = (data) => {
  var html = "";
  data.list.forEach((item) => {
    html += `<div>${item.name}有${item.num}个</div>`;
  });
  return html;
};
//服务
http
  .createServer((req, res) => {
    res.writeHead(200, { "Content-Type": "text/html" });

    const html = dataToHtml(fetchData());
    res.end(
      `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>传统 ssr</title> </head> <body> <div id="root"> ${html} </div> </body> </html> </body> `
    );
  })
  .listen(9001);
console.log("server start...9001");

用 JAVA 无法解决的问题

  • 保证 SSR 代码可以做 CSR 降级,比如接口数据用 java 获取,在 CSR 里面就无法复用请求数据的逻辑
  • 现在前端都是用 react/vue 开发,如何用获得的数据,渲染这个页面以及依赖子组件,在 JAVA 里面执行 react 相关服务端渲染逻辑非常困难,需要 java 有相关操作 react 的类,而 react 开源框架要封装一套 java 类
  • 模板要组件化的方式来开发,因为模板的代码大概率是前端开发,所以要考虑解决 ES6+ 代码编译的问题,同样 JAVA 和 PHP 搞起来很难,要借助 babel 等工具

下图是 react ssr 的核心的流程 image.png

总结

现在看,如果不用 node 来组织服务端渲染,改成 java 渲染,有很多问题目前无法解决,不是不可以用 java 只是现在已经没有完整的 java(或者其他后端语言) 服务端渲染的社区环境了。