Hello, 同构 -- 同构技术的简单梳理

1,233 阅读5分钟

我们都知道共享单车,商场里的共享充电宝,凉凉的共享办公,接下来可以了解下代码的共享技术,同构。

同构指的是,同一份代码,既可以实现浏览器端的渲染,也可以实现服务器端的渲染,可以说,非常“共享”了。

接下来就展开讲讲这个共享代码的同构。

服务器端渲染

服务器端渲染,指的是服务器先生成好 HTML, 浏览器请求到 HTML,可以直接进行渲染。

像是 JSP, PHP 等技术,都能够实现服务器端渲染 。服务器接收到浏览器发出的请求,依据这个请求再去获得数据,然后根据数据产生 HTML, 返回给浏览器。

浏览器端渲染

现在如日中天的 React 和 Vue, 默认的方式即为浏览器端渲染。

浏览器端渲染。即页面初始请求的 HTML 中没有可展示的内容,内容要 JavaScript 来添加到页面中。

在无缓存的情况下,浏览器端渲染至少要经过以下三个 HTTP 请求,用户才能在浏览器看到有意义的内容:

  1. 向服务器请求 HTML。这个时候获取的 HTML 是没有任何内容的,只是给了即将渲染的 HTML 一个容器,让接下来的内容快到碗里来。

  2. 向服务器请求 JavaScript. 这次请求的 JavaScript 就负责把内容放之前的空白 HTML 里面去,但是渲染内容之前,还要根据页面请求,向服务器请求相应的数据。

  3. 向服务器请求数据。这步就是上一步的 JavaScript 访问相应的 API, 来获取数据的请求。

经过上面三个请求,JavaScript 才能把有意义的内容添加到页面中。

有一个网页性能指标,叫 TTFP (Time To First Paint), 指的是从用户发起请求开始,到用户看到有意义页面内容的时间差。

经过上面三个请求,也代表着浏览器端渲染的 TTFP 并不会那么如人意。

现在来看下服务器端渲染和浏览器端渲染各自有什么优缺点。

服务器端渲染 VS 浏览器端渲染

第一回合,TTFP (Time To First Paint):

  • 服务器端渲染只要一个请求,就能取得带内容的 HTML,浏览器直接渲染,干净利落。
  • 浏览器端渲染要走至少三个请求,才能“慢悠悠”地渲染出内容。

服务器端渲染胜出。

第二回合,服务器压力:

  • 服务器端根据请求获取数据,并生成 HTML 页面。服务器要接受浏览器的请求,并且要发出请求获取数据,然后居然还要生成页面。
  • 浏览器渲染,请求数据和生成 HTML 都是在浏览器来完成的,浏览器分担了服务器的压力,服务器再也不会肾虚。

浏览器端渲染胜出。

第三回合,SEO (Search Engine Optimization):

  • 浏览器渲染直接生成了 HTML,对搜索引擎的爬虫可以说非常友好了。
  • 大多数搜索引擎识别的主要内容还是 HTML,对 JavaScript 识别能力就很弱。

服务器端渲染胜出。

第四回合,用户体验:

  • 传统服务器端渲染针对页面请求,生成相应的 HTML 文件。假如一个页面只需要局部更新,然而给浏览器的是一个局部更新了的新页面,要刷新一下才能得到预期效果,用户体验差了不说,这也是一种资源的浪费。
  • 浏览器渲染,局部更新时,JavaScript 请求到数据,替换页面内容,体验很好了。而且凭借 React 和 Vue 的虚拟 DOM,浏览器的各种花式交互还不是说来就来。

浏览器端渲染胜出。

两种方式各有优缺点,而同构,就是两种方法都使用,取其精华。

同构

同构将服务器端渲染和浏览器端渲染结合起来。

一开始提到共享代码,拿 React 来说,服务器端和浏览器端共享的代码就是组件的代码。理想情况下,组件既能够在浏览器端渲染,也可以在服务器端渲染产生 HTML. 同一份代码可以在不同的环境下运行。

同构的共享的组件代码是要执行两次的,先是在服务器端生成 HTML, 返回给浏览器渲染;然后 JavaScript 在浏览器再执行一次渲染,来接管页面的交互。

优点

渲染两次明显是种浪费,但是现有方法已经解决了这个问题。在 React 的同构中,实现服务器端渲染的关键方法 ReactDOMServer.renderToString 将组件转换为 HTML,,当浏览器端的 JavaScript 运行的时候,只是添加事件绑定等操作,并不会重新渲染,这个方法是 React 同构快速首屏加载的关键。

在同构之后,站点具备了服务器渲染和浏览器端渲染的优点:

  • SEO 友好了,因为服务器返回了 HTML.

  • TTFP (Time To First Paint) 时间很短,用户能很快看到页面内容。

  • 用户体验好了,实现局部更新,并且各种交互都不在话下。

总结

使用同构,也需要有一定的考量,

  1. 若是对 TTFP 没有太高的要求,没有必要使用同构,因为随着浏览器端渲染的发展,浏览器端的代码性能越来越高,浏览器端渲染的速度也不会慢得那么夸张,尤其是用肉眼考量的情况下。
  2. 同构也具备服务器端渲染的缺点,会对服务器造成很大的压力。浏览器端渲染的情况下,服务器只用提供静态资源,而服务器端渲染要生成 HTML, 无疑增加了服务器的压力。

假如希望应用的性能更好,并且服务器资源充足,可以尝试同构。