传统客户端渲染流程CSR
先说说客户端渲染流程:经过域名解析,三次握手后,客户端请求到资源,先是拿到一个没有内容的html文件,然后加载js,拿到所有资源,由js动态生成内容,包括接口调用,路由分发,逻辑处理等等。。然后用户才能看到完整的页面
显而易见带来的问题是首屏加载慢,且不利于SEO
服务端渲染SSR
什么是服务端渲染
服务端渲染顾名思义就是在服务端完成渲染,其实最开始前后端不分离的JSP/PHP/Python也都属于服务端渲染。众所周知React是用于构建ui的JavaScript库,得益于node的强大功能,所以说js运行在服务器上是可行的,React也提供了相关Api。
简单说说服务端渲染流程:客户端发起请求拿资源,前端node服务器接收到请求,根据路径加载各种组件并编译生成一个有网页内容的html字符串返回给客户端,浏览器拿到这个html字符串就可以直接渲染页面,此时的页面没有交互功能,浏览器解析html字符串的时候当解析到js代码时,就会加载执行js,js执行完毕,页面就有了交互功能。
为什么要使用服务端渲染
减少了首屏渲染的时间:很明显浏览器第一次拿到资源就是有内容的html文件,在用户感知来看,有画面出来的第一时间就是少。
有利于SEO优化:服务端编译生成html字符传给到客户端直接渲染,那么就可以在node服务端生成字符串的时候做SEO优化。
服务端渲染的难点
实现难点是同构,需要客户端和服务端同时编译复用一套代码,面临各种问题
同构主要分为组件同构,数据同构以及路由同构
- react提供了renderToString()方法用于把组件编译成Dom字符串,从react16版本开始,推荐使用renderToNodeStream()方法。前者方法会把组件编译完成后吐给客户端,而后者则是类似于’流‘的概念返回给客户端,,,但是renderToNodeStream()方法只能运行在服务端。
- 数据同构其实就是保证服务端和客户端数据一致。next提供了getiInitialProps()这个异步方法用于初始数据填充
- 脱水: 服务端获取到数据塞到页面编译返回给客户端叫做数据的脱水
- 注水: 客户端拿着数据去执行js,初始化组件,接管页面,叫做数据注水
- 路由同构。区分客户端和服务端:服务端使用StaticRender组件包裹根组件,客户端使用BrowserRouter来包裹根组件