时间停止
背景/问题
由于不得已需要在前端做一个路由跳转判断,其中是否判断需要请求接口,为了尽快触发判断,相关逻辑置于 head 里面尽早执行,形如
1 | <html> |
将代码置于 head 确实能第一时间运行,然后问题是他需要等待一个接口的异步返回,之后才能做判断。
这就导致了实际判断逻辑需要等待非常长的时间。
因为当代码同步执行完,页面其他正常的资源就会开始加载,页面渲染也会不断进行。这个时候即使接口很快返回,但因为整个页面处于一个高占用的时间(资源的加载和解析执行,页面的不断重新渲染),回调也无法及时响应。
最终,在实际的业务场景中,接口返回其实只要不到 100ms ,但是从请求发出到触发跳转将近要 1.5s-2.5s 甚至更高的时间,需要等待多了将近 20 倍的时间。
stop the window
为了加速这个过程,想了好几个方法,都不怎么有效。关键是始终无法绕开资源加载解析对主线程的占用问题。
也并没有一个可以人为提高网络请求回调的优先级的方法。
这个时候我突然发现了一个神奇的 api Window.stop()
简而言之,她就相当于浏览器刷新时点击地址栏旁边的 x ,其后整个 web 所有资源请求逻辑都会暂停下来。
没有了各种资源请求,脚本执行解析,js 线程占用瞬间空闲下来,此时就可以尽快响应执行相关逻辑了。
不过这也有另一个问题:
执行 stop()
之后就真的是 stop the world 而且无法恢复,那么如果判断到不需要跳转,希望元页面的资源逻辑继续加载的时候该怎么办呢?
很简单,直接 window.reload()
让整个页面字面意义上的重新加载即可。
不过这个时候也需要做一个简单的判断逻辑,让这个时候的 reload 跳过相关逻辑,避免死循环不断 reload
伪代码如下
1 | const isReload = localStorage.getItem('isReload') |
结
这个 api 是一个非常老的 api,几乎除了 ie 不需要考虑兼容性。
如果当你有万不得已需要 stop the world
的时候确实可以放心使用。
不过,话又说回来,需要把重定向放到前端判断的逻辑就已经够扭曲了