在服务端渲染完成后,静态页面将被传送给客户端,接下的来客户端开始获取应用资源,启动应用,一切和往前一样,如果打开控制台,观察network,你会发现当前页面上所需要的网络请求正常的被发送。你是否意识到请求被重复发送了!
为什么重复?
服务端渲染时的过程和客户端其实差不多的,该发的网络请求得发,否则页面的数据从何而来?假如页面 A 上有2处需要从服务器获取数据,服务端渲染及应用启动的过程是:
根据用户发起的url和已经打包好的客户端代码,使用 renderModuleFactory 生成静态页面,在此过程中发出2个请求获取数据
服务器发送静态页面给客户端。
客户端展示静态页面。
客户端获取应用完整资源。
官户端启动应用并定位到用户当前的页面。
进行入页面的生命周期,再次发送那2个请求,此后的过程和客户端渲染一样。
很明显,网络请求在第1,6两步上重复了,页面可能被重绘,发生抖动等。
解决方案
为了解决这个问题,需要把上述第一步的数据保存起来,当第6步的请求发送时,我们只要看下是否有保存的数据,如果有的话就不再发送请求。另外我们需要知道请求是否是在服务端渲染时发出的。先看代码:
代码引用自:https://blog.angular-university.io/angular-universal/
这是一个进入某个路由前的resolove守卫,用来获取页面上所需要的数据,首先使用当前路由上的ID参数和一个自定义的前缀‘course-’,通过makeStateKey函数生成一个key,接下来判断了transferState上是否有这个key值对应的数据,有的话直接将获取到的数据返回,同时删除transferState上的这个key。在没有找到对应key的状态时,给服务器发送了一个请求,同时在请求回来时通过tap操作符,判断当前应用的环境,如果是服务器环境,则把取到的数据通过 transferState 保存。那么数据究竟保存在哪里?
控制台 ---> network ---> 找到请求(类型是document) ----> response,翻到最下面,你会发现一个script标签,页面上的数据就安静的躺在这里。如下图:
领取专属 10元无门槛券
私享最新 技术干货