Vue3 的项目,客户那边习惯把同一个项目通过多个浏览 Tab 去打开,这样就能很方便去使用多个页面

这部分相同的逻辑依赖的是同一个接口,同一个处理数据的逻辑,并且这两个过程都很耗时:
- 请求接口:3000ms,因为后端取数据逻辑很复杂,返回数据量很大!
- 数据处理:300ms,前端拿到数据得处理一下
既然都是同一个逻辑,那么能不能将页面一的数据给页面二、页面三、页面四用啊?
分析优化点
接口请求 和 数据处理 都是比较耗时和数据量大的操作,所以我一开始是想放到 WebWorker 中去做的
但是当客户提出优化点后,我就发现不能用WebWorker 去做,原因如下:
- 1、每个 Tab 的WebWorker都是独立的,无法进行数据共享
- 2、就算用 WebWorker + IndexedDB 去做数据缓存共享,但是却很难共享数据状态
第二个原因可能有些人不理解,为什么要共享数据状态呢?

举个例子

- 情况一: 页面一打开并点击按钮进行数据请求处理和缓存,再去点击页面二的按钮,那么页面二肯定能拿到缓存的数据,这种情况没问题
- 情况二: 页面一点击按钮1秒后,去点击页面二的按钮,这个时候页面二是不知道页面一的数据状态的,所以页面二不知道是要发起请求呢,还是要去等页面一请求完呢
所以共享数据状态很重要
SharedWorker
SharedWorker 是 HTML5 中引入的一种 WebWorkers 类型,用于在浏览器中创建可在多个浏览器窗口或标签页之间共享的后台线程。Web Workers 是在主线程之外运行的脚本,允许执行一些耗时的任务而不会阻塞用户界面。
SharedWorker接口代表一种特定类型的 worker,可以从几个浏览上下文中访问,例如几个窗口、iframe 或其他 worker。它们实现一个不同于普通 worker 的接口,具有不同的全局作用域,SharedWorkerGlobalScope 。
备注: 如果要使 SharedWorker 连接到多个不同的页面,这些页面必须是
同源的(相同的协议、host 以及端口)。
又称共享线程。之所以可以在多个浏览器页签中共享信息,是因为在页签的html中创建SharedWorker时,如果第一个参数相同,则视为同一线程,所以只要保证创建时的第一个参数相同,就可以在多页签间共享信息。
可以理解为: SharedWorker 类似于 WebWorker ,只不过SharedWorker 能让多个 Tab 标签页共享
多个 Tab 连同一个SharedWorker 的时候, SharedWorker会通过 port 来管理每一个 Tab,可以说:一个 Tab 就是一个 port
我们通过一个小案例来演示一下 SharedWorker,我们看看 count能不能被两个页面共享


可以看到 count被共享了~

现在我们把 shared-worker.js 里的逻辑改成请求数据和处理数据的代码


这样写的话显然共享不到数据状态!这样相当于是请求了两次,跟没优化一样。页面一先点,后再点页面二,按理说如果共享了,应该是同时出现数据才对,显然现在还没实现最终效果
所以我们需要实现数据状态共享,其实很简单,利用Promise就行了~

这样才是最终效果,不同时点击,但是出现数据确是同时的
