同构
React组件既可以在浏览器端渲染,也可以在服务器端渲染产生HTML,代码可以运行在不同的环境下,这种方式叫“同构”服务端渲染
对于来自浏览器的HTTP请求,服务器通过访问存储器或者访问别的API服务等方式获得数据,然后根据数据渲染生成HTML返回给浏览器,浏览器只需要把HTML渲染出来。
- 优点
利于SEO
加速首屏渲染
大多数情况下,服务器获取数据比浏览器端获取数据要快 - 缺点
页面大小对性能的影响,如果服务器端产生的HTML过大,首页下载的HTML要比纯浏览器渲染要大,这样下载HTML的时间会增长,服务器渲染未必能获得更好的性能
- 浏览器端渲染
服务器返回的HTML只包含几个无内容的元素作为页面框架,网页中引用的JavaScript会直接访问API服务器来获取数据,取到的数据再结合模板来生成HTML字符串,插入到页面框架总,产生了用户最终看到的界面。
模板库的效率并不是很高,用户需要等待API请求成功之后才能看到第一条内容,反而让用户感觉更慢了,并没有提高用户体验。 - 完全浏览器渲染技术
- 各种应用框架,包含路由和应用结构功能
- 模板库
服务器端的API支持
传统的模板库就是DOM树的操作,将HTML字符串插入到网页中,无论如何优化都有它的极限。
React的Virtual DOM工作原理,配合生命周期函数的应用,性能不是字符串替换的模板库能够比拟的。
完全浏览器渲染的缺点:
首页性能,首页加载白屏问题
不利于SEOReact同构
用户第一请求页面时候,node服务端做初始渲染,node服务端接受到请求后,把需要用的HTML渲染成HTML字符串,返回给客户端,之后,客户端接管渲染的控制权限
NODE服务端渲染
Redux在客户端提供应用初始所需的state,客户端把服务端返回的state作为初始的state
发送响应前用ReactDOMServer.renderToString(el)渲染初始的HTML,渲染时会计算所生成HTML的校验和,并存放在根节点的属性data-react-checksum中
服务端最后一步就是把初始组件的HTML和初始state注入到客户端能够渲染的模板中。
state的传递通过script标签来吧preloadedState赋给window.INITIAL_STATE
注入js bundle文件
客户端就可以通过window.INITITIALSTATE__来获取preloadedState,浏览器客户端渲染
从window.INITIAL_STATE得到初始的state,并传递给createStore()
页面加载js后,打包JS启动,调用React.render()重新渲染一遍React组件,在重新计算DOM树之后,也会计算一遍校验和,和服务器的校验和做一个对比,如果二者相同,就没有必要做DOM操作了。然后会与服务端渲染的HTML的data-react-id属性做关联。这会把新生成的React实例与服务端的虚拟DOM连接起来。因为同样适用了来自Redux Store的初始state,并且view组件代码是一样的,结果就是我们得到了相同的DOM
如果服务器端渲染和浏览器端渲染产生的内容不一致,用户会先看到服务器端渲染的内容,浏览器端生成的DOM树,覆盖掉服务器产生的HTML,用户会看到一次闪烁。
实现同构一定要保正服务器端和浏览器段渲染的结果一致。