<深入浅出React和Redux> - 同构

杨旭 bio photo By 杨旭

同构

同构: 同一份代码可以在不同环境下运行, 功能呢组件能够在客户端渲染, 也能够在服务端生成HTML

服务器渲染 vs 浏览器渲染

万维网是从服务端渲染发展起来的, 所有的页面都是静态HTML文件, 但是没法提供动态内容

随着CGI技术的出现, 使得服务器端终于可以产生动态内容了, 但是依然是在服务器端生成HTML, 只是结合了数据和模板

服务器渲染统治了很长时间, 直到AJAX技术的出现, 使得网页可以做到局部刷新

直到之后的浏览器端渲染:

  • 一个应用框架: 包含路由和应用结构功能
  • 一个模板库: 以数据为输入, 输出的就是HTML字符串
  • 服务器端的API支持: 提供数据的API服务器

在React应用中, 可以将网页内容, 动态行为, 以及样式全部封装在同一个组件中, 把浏览器端渲染发挥到了极致

虽然浏览器端渲染很强大, 但是还有一个问题需要解决: 首页性能

  • TTFP(Time to First Paint) 从HTTP请求发出, 到第一个有意义的内容渲染出来的时间差
  • TTI(Time to Interactive) 从HTTP请求发出, 到用户可以交互的时间差

TTI一定是大于TTFP的, 这两个指标的时间越短越好

在打开一个页面时, 不考虑缓存, 最坏需要三个请求:

  • 向服务器获取HTML
  • 解析HTML后获取JavaScript文件
  • 访问API服务器获取数据

相对来说, 服务端渲染的优势在于:

  • 第一个HTTP请求就能够返回有意义的内容
  • 有利于搜索引擎优化

但是使用服务端渲染有多种因素需要考虑:

  • 服务器获取数据快还是浏览器获取数据快?
  • 服务器产生的HTML过大是否会影响性能?
  • 运算是否是服务器能够承受的起的?

React同构

React本身并不是被设计用来服务端渲染的, 但是React因为其构建理念, 他非常适合用来做同构.

为了支持同样代码两端运行, 服务器端同样需要能够运行JavaScript, 所以需要Node.js作为服务器

为了实现同构, 需要实现以下功能:

  • 在服务器端根据React组件生成HTML
  • 数据脱水和注水
  • 服务器端管理Redux
  • 支持服务器和浏览器获取共同数据源

React服务器端渲染HTML

React在客户端渲染使用render()函数, 最终产生的是DOM元素, 而在服务器端, 最终产出的是HTML字符串

客户端实际渲染之前, 会计算HTML字符串的校验和, 如果与上一次相同, 就不会重新渲染了

脱水和注水

服务器渲染时, 除了要返回HTML字符串, 除此之外还需要脱水数据, 用来注入到React组件中, 当浏览器渲染时, 根据脱水数来渲染组件, 这个过程叫做注水.

脱水数据的传递方式, 一般是在页面中内嵌一段JavaScript, 内容就是把传递给React组件的数据赋值给某个全局变量

服务器端Redux Store

服务器端渲染最大的区别是, 要为每个用户创建一个新的Store

支持服务器和浏览器共同获取数据

// todo

服务器端路由

// todo