为了保证页面访问性能最佳,咱们一般在服务端会设置缓存策略,好比说带有 hash 类型的文件会设置过时时间为永久,
非 hash 文件好比 html 等其余文件设置了通用的缓存策略,即:根据 etag 或者 last-modified 来判断文件是否更改,
而后返回 304 代码告知浏览器不用下载,从而保证页面最新。这些策略在页面加载性能和版本维持最新之间保持了平衡。javascript
一般使用上述策略可以保证页面最新。可是有时候会出现两种状况致使页面非最新:浏览器缘由和服务端缘由。html
使用 etag 或者 last-modified 存在的问题
etag 是提供文件指纹的标识,这个标识的实现能够经过多种方式,方式的实现关系着文件是否最新。一般状况下 etag 出现没法刷新的状况比较少,
出现问题可能是因服务器文件系统或者静态文件服务出现了问题。另外一种方式是使用 last-modified(部分etag 也可能使用了时间戳)。last-modified
的精度是精确到秒,对于服务器文件来讲这远远不够,1 秒内文件变更可能超过一次,或者出现文件变更但时间戳没有变化的状况,
致使不论客户端怎么刷新都是返回 304 代码,页面没法更新到最新前端
浏览器自身缓存
若是是遵照 http 规范,保证每次页面加载时都使用服务端内容,那么就不存在缓存问题。但实际上浏览器为了提升性能,
总会进行缓存。好比说 safari 下页面会整个被缓存起来,chrome 在输入已有网址时会优化从 dist cache 中获取文件,
而不会去请求服务器。java
对于服务端致使的缓存问题,须要排查出现 304 的缘由,针对性的解决,这里就再也不介绍了。chrome
对于浏览器的问题,有两种:页面所有缓存和只是缓存文件。json
所有缓存页面
这种状况一般出如今 safari 后退或者内存不够从新加载时,特色是页面全部信息都被缓存起来,这时候想要从新请求页面文件是没有任何办法的,
只能上显示时判断是否须要进行页面的刷新。因为页面缓存后不执行 onload 事件,须要在 onpageshow 事件中判断是否须要从新加载页面。浏览器
文件被缓存
前端页面缓存的判断是包含了文件是否为最新的判断。缓存
最简单的作法是提供一个 API,保存版本信息,每次加载时请求最新版本信息,
若是不是最新则提示。基本逻辑以下:服务器
fetch('/page/version').then((res) => res.json()) .then((res) => { if (res && res.version && res.version !== 当前的版本) { 提示或者刷新 } })
遇到的问题是:当前页面的版本如何保存和怎么变更工做量最小?antd
版本保存咱们能够以文件的方式进行保存,经过 import 后,固定在代码中。这样就能够实现基本的工做。
基础实现存在的问题是:版本须要提供独立的 API,对于前端来讲配合过程太麻烦。那么咱们就考虑下版本信息放在文件中。
放在文件中首先要解决的一个问题是:文件会被缓存,并且比较严重。解决这个问题就在 url 中添加时间戳,保证每次 URL 不一样,
最终作法以下:
代码以下(使用 antd 中的 notication 进行通知,其余类型的通知也相似):
import { notification } from 'antd' import page from '../../public/pageVersion.json' fetch(`/pageVersion.json?_=${Date.now()}`).then(res => res.json()) .then((res) => { if (res.version && page.version !== res.version) { notification.open({ message: '页面过时', description: `当前页面已通过期,最近更新时间为${res.updateTime},请手动刷新浏览器页面以便获取更好体验`, duration: null }) } }) export default {}
固然,你能够作一些交互或者其余更复杂的操做,彻底看我的需求了。