【这是我参与更文挑战的第13天,活动详情查看: 更文挑战】
react ssr
原理很容易理解,但是仅仅理解这点还不够足以搭建应用骨架,其中最有难度的内容应该是同构。
虚拟dom
平时我们都习惯使用
jsx
来编写react
的组件。但jsx
只是一个抽象的语法糖,看上去是写组件,其实我们写的是对象,只是这样写更方便,更符合我们前端开发者的编写习惯,看上去就像写html
,多爽。 虚拟DOM
除了在渲染时用于提高渲染性能,以最小的代价来更新视图的作用外,另一个作用就是为组件的跨平台渲染提供可能。 虚拟DOM
本身 就是一个内存中的对象,通过对象的属性来描述要渲染的具体是什么元素以及内容。
如下:
<nav className="nav">
<h1 className="nav-item">首页</h1>
<h1 className="nav-item">文章</h1>
<h1 className="nav-item">工具</h1>
<h1 className="nav-item">关于</h1>
<nav>
上面的结构可以转换为下面的对象表示(虚拟 dom)
const tree = {
tag: 'nav', // 节点标签名
props: { // DOM的属性,用一个对象存储键值对
class: 'nav'
},
children: [ // 该节点的子节点
{tag: 'h1', props: {class: 'nav-item'}, children: ['首页']},
{tag: 'h1', props: {class: 'nav-item'}, children: ['文章']},
{tag: 'h1', props: {class: 'nav-item'}, children: ['工具']},
{tag: 'h1', props: {class: 'nav-item'}, children: ['关于']},
]
}
既然有了这样的对象,我们就可以轻松的把这个对象转换我们想要的表现形式,比如
html
格式,而这个html
就是我们要直出的内容。不过这个转换的过程不需要我们来完成,react
已经帮我们完成,其本身就已提供了内置方法来支持服务端渲染。
同构
所谓同构,就是指前后端公用一套代码,比如我们的组件可以在服务端渲染也可以在客户端渲染,但都是同一个组件。
当然打造同构应用还有另外一个得天独厚的条件,双端使用同一种语言 - javascript。
SSR
部分我们使用node
就能完成,所以我们才可以编写同一套代码供双端执行。 另外还有一个重要的特性也是同构的重要体现,浏览器接管页面后的进一步渲染(交互、事件)过程中,会判断已有的DOM
结构和浏览器渲染出的结构是否相同,若相同,则不重复渲染,只需要绑定事件即可
双端对比机制
为了实现服务端渲染,打造同构应用,React
内部实现了相关的API
,可以让我们方便的将一个组件转换为html
字符串。
要使用的api:
// ReactDOMServer 类可以帮我们在服务端渲染组件 - 得到组件的 html 字符串。
import ReactDOMServer from 'react-dom/server';
该模块下有个方法:
- renderToString() 把一个react组件渲染为原始的HTML
ReactDOMServer.renderToString(element)
用这个方法在服务端生成
HTML
字符串,然后将该字符串返回给浏览器端,完成页面内容的初始化,同时让搜索引擎可以抓取你的页面来达到优化SEO
的目的。
- renderToStaticMarkup(); 该方法是为了将组件渲染为
html
字符串,不会带有data-react-checksum
属性。
ReactDOMServer.renderToString(element)
和上面方法的能力不同,当然使用场景也不同,如果只是单纯服务端渲染的话可以用该方法,性能肯定要比上面的方法高,因为不需要计算嘛,还能减少直出的内容体积。
性能
在浏览器端渲染时,该方法会最大限度的保留服务端使用renderToString()
渲染的内容,同时添加事件绑定等交互。
- renderToNodeStream 和 renderToStaticNodeStream
另外
react 16
在性能上还做了改进,提供了可以将组件转换为字节流的renderToNodeStream
方法。其实使用renderToNodeStream
或者renderToString
对最终的渲染结果没有影响。不过renderToNodeStream
的性能要好的多,可以有效缩短TTFB
时间。因为组件渲染为字符串,是一次性处理完后才开始向浏览器端返回结果。而采用流的话,可以边读边输出,可以要让页面更快的展现,缩短首屏展现时间。
同构应用时序图