SSR,俗称 服务端渲染 (Server Side Render),讲人话就是: 直接在服务端层获取数据,渲染出完成的 HTML 文件,直接返回给用户浏览器访问。

非SSR:前后端数据分离,请求到html后再请求了数据,由js将数据填入new dom里 动态更新到html上
痛点:

  • 首屏渲染性能瓶颈:
    • 空白延迟: HTML下载时间 + JS下载/执行时间 + 请求时间 + 渲染时间。在这段时间内,页面处于空白的状态。
  • SEO 问题: 由于页面初始状态为空,因此爬虫无法获取页面中任何有效数据,因此对搜索引擎不友好。
    • 虽然一直有在提动态渲染爬虫的技术,不过据我了解,大部分国内搜索引擎仍然是没有实现。

既要保证现有的前端独立的开发模式,又要由服务端渲染,因此我们使用 React SSR。

原理:

  • Node 服务: 让前后端运行同一套代码成为可能。
  • Virtual Dom: 让前端代码脱离浏览器运行。

条件: Node 中间层、 React / Vue 等框架。 结构大概如下:
image.png

server数据脱水

  1. import serialize from 'serialize-javascript'
  2. // 获取数据
  3. const initState = store.getState()
  4. const html = `
  5. <!DOCTYPE html>
  6. <html lang="zh">
  7. <head></head>
  8. <body>
  9. <div id="App"></div>
  10. <script type="application/json" id="SSR_HYDRATED_DATA">${serialize(initState)}</script>
  11. </body>
  12. </html>
  13. `
  14. ctx.status = 200
  15. ctx.body = html
  1. 使用了serialize-javascript序列化 store, 替代了JSON.stringify,保证数据的安全性,避免代码注入和 XSS 攻击;
  2. 使用 json 进行传输,可以获得更快的加载速度;

client数据吸水:初始化 store 时,以脱水后的数据为初始化数据,同步创建 store。

  1. const hydratedEl = document.getElementById('SSR_HYDRATED_DATA')
  2. const hydrateData = JSON.parse(hydratedEl.textContent)
  3. // 使用初始 state 创建 Redux store
  4. const store = createStore(reducer, hydrateData)

前后端注入的这个redux inistate是同源的,
问题:如何保证的,前端维护的全局状态,后端是知道的
(因为前端维护的全局数据状态 ,不一定就只有后端的那些数据

参考资料

react-ssr