我们都知道共享单车,商场里的共享充电宝,凉凉的共享办公,接下来可以了解下代码的共享技术,同构。
同构指的是,同一份代码,既可以实现浏览器端的渲染,也可以实现服务器端的渲染,可以说,非常“共享”了。
接下来就展开讲讲这个共享代码的同构。
服务器端渲染
服务器端渲染,指的是服务器先生成好 HTML, 浏览器请求到 HTML,可以直接进行渲染。
像是 JSP, PHP 等技术,都能够实现服务器端渲染 。服务器接收到浏览器发出的请求,依据这个请求再去获得数据,然后根据数据产生 HTML, 返回给浏览器。
浏览器端渲染
现在如日中天的 React 和 Vue, 默认的方式即为浏览器端渲染。
浏览器端渲染。即页面初始请求的 HTML 中没有可展示的内容,内容要 JavaScript 来添加到页面中。
在无缓存的情况下,浏览器端渲染至少要经过以下三个 HTTP 请求,用户才能在浏览器看到有意义的内容:
-
向服务器请求 HTML。这个时候获取的 HTML 是没有任何内容的,只是给了即将渲染的 HTML 一个容器,让接下来的内容快到碗里来。
-
向服务器请求 JavaScript. 这次请求的 JavaScript 就负责把内容放之前的空白 HTML 里面去,但是渲染内容之前,还要根据页面请求,向服务器请求相应的数据。
-
向服务器请求数据。这步就是上一步的 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) 时间很短,用户能很快看到页面内容。
-
用户体验好了,实现局部更新,并且各种交互都不在话下。
总结
使用同构,也需要有一定的考量,
- 若是对 TTFP 没有太高的要求,没有必要使用同构,因为随着浏览器端渲染的发展,浏览器端的代码性能越来越高,浏览器端渲染的速度也不会慢得那么夸张,尤其是用肉眼考量的情况下。
- 同构也具备服务器端渲染的缺点,会对服务器造成很大的压力。浏览器端渲染的情况下,服务器只用提供静态资源,而服务器端渲染要生成 HTML, 无疑增加了服务器的压力。
假如希望应用的性能更好,并且服务器资源充足,可以尝试同构。