微信返回Vue SPA不刷新页面的问题记录

问题表现

在微信内,打开SAP的页面SPA-a,从SPA-a打开外部页面B,从B再返回SPA-a的话,SPA-a页面会呈现Vue数据绑定特征失效的症状,比如load完接口,loading窗口不会根据v-show变化而消失,点击路由跳转SPA,页面也没有出现变化,但实际上路由的hash已经变化了,但是页面内容没有跟着变化。

问题分析

本来只是以为是页面loading窗口没有隐藏之类的问题,对loading的值进行核对,观察v-show绑定的值是否有变化,实际上,是有对store里面的loadingSHOW进行赋值的,但template没有变化或者没有进行重新render。

问题总结

浏览器前进/后退缓存

这里提到一个概念,浏览器前进/后退缓存(Backward/Forward Cache, BF Cache),当然也有人叫 disk Cache。
BF Cache 是一种浏览器优化, HTML 标准并未指定其如何进行缓存,因此缓存行为是各浏览器各自实现,所以不尽相同。
由于不是 HTTP 缓存,所以通过头文件缓存设置 no-cache 是无效的。当然也不能以 HTTP 缓存机制来理解 BF Cache。

作者:Sakura同志
链接:https://juejin.im/post/5caf3462e51d456e7e297b9e
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

形成这样的根本原因是微信对于其内置的浏览器进行的“优化”,在iOS下返回SPA-a的时候,微信不会重新请求任何HTML/JS/CSS静态资源,只会把JS重新执行一遍。

但是按照我的个人理解,JS重新执行一遍,应该也能够形成一样的执行效果才对。实际上的vue整个的生命周期也确实有重新执行,但就是已经失去了双向数据绑定的响应了。

但实际上表现和期望的不一致,可能是我的理解有偏差。

问题调试过程

  1. 尝试一:一开始的思路是着重于在返回SPA-a的时候,尝试去刷新SPA-a。由于sessionStorage会计算路由的历史记录count的计数,以此为判断当count等于1(为什么等于1,有另外原因,不在此细说)的时候,尝试使用location.reload()去刷新页面。
    1. 结果,失败,reaload也没有重新加载页面。
  2. 尝试二:由于SPA-a是之前相同业务的迁移,而之前业务并没有出现过这样的情况。通过对比,猜测是由于之前业务是使用动态引入路由页面的,所以对SPA-a的项目进行了相同改造。
    1. 结果,成功。

结论

  1. 微信会对之前访问过的页面进行 前进/后退缓存(disk cache),返回被缓存的页面不会执行静态资源的请求,只会重新执行JS。
  2. vue SPA在被disk cache之后,返回SPA,不会具备双向绑定的特性。
  3. 第二点可以用异步引入路由组件解决。