通过缓存清除处理 SPA 更新 - 处理部分加载的页面

问题描述 投票:0回答:1

我正在开发一个(静态)单页应用程序,使用 Vue3 和 Vite 与 RestAPI 进行通信,并且我启用了缓存清除以确保客户端始终收到我的资产的最新/匹配版本(更新时)。但是,我面临一个问题,即使用旧版本 SPA 的用户在导航到尚未加载的页面时尚未加载所有文件。

场景如下:

  1. 用户在运行旧版本时访问我的 SPA。
  2. 他们导航到几个页面,但尚未加载所有资源。
  3. 我通过替换 docker 容器来部署新版本的 SPA。
  4. 用户尝试导航到他们之前未访问过(因此未加载)的页面,他们遇到了 SPA 卡住的情况,因为它无法加载丢失的模块

我的问题是:

  • 处理此类情况的最佳做法是什么?

  • 如何确保 SPA 自动刷新/清除浏览器缓存?

  • 在 SPA 中使用缓存失效的资产时,我应该遵循哪些模式或技术来避免这些问题?

我正在寻找有关如何优雅地处理此问题并确保更新期间流畅的用户体验的指导,特别是对于可能缓存了旧资产的用户。因为目前他们需要强制刷新缓存(如果他们知道如何在子页面未加载时解决问题)。非常感谢任何帮助或见解!

vuejs3 single-page-application vite browser-cache
1个回答
0
投票

通常在 SPA 中,您会为图像、JavaScript 和 CSS 等文件打开 HTTP 浏览器缓存。然而,对于 HTML 文件,您可以显式禁用浏览器缓存。这会产生与此类似的代码,如我的 SPA 代码示例的 Web 主机中所使用的。

private _getCacheControlResponseHeader(request: Request): string {

    const fullUrl = `${request.protocol}://${request.hostname}${request.originalUrl.toLowerCase()}`;
    const path = new URL(fullUrl).pathname;
    const extensions = [
        '.js',
        '.css',
        '.ico',
    ];

    const cacheableExtension = extensions.find((ext) => {
         return path.endsWith(`${ext}`);
    });

    if (cacheableExtension) {
        return 'public, max-age=31536000, immutable';
    } else {
        return 'no-cache, must-revalidate';
    }
}

结果是每次应用程序加载时,它都会向服务器请求 HTML 文件,服务器通常会返回 304 notmodified 响应。当 HTML 文件升级时,会下载 HTML 文件的新版本,其中包含与此类似的缓存清除时间戳。结果应该是可靠的端到端部署:

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8'>
        <meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'>

        <base href='/spa/' />
        <title>OAuth Demo App</title>

        <link rel='stylesheet' href='bootstrap.min.css?t=1696156680953' integrity='sha256-r5XY+61xZLKtKXLNHBmCfLfQqRnhOud395lWucqjb14='>
        <link rel='stylesheet' href='app.css?t=1696156680953' integrity='sha256-uyU8ojtDL+l+a2gYIn6fJNKuwi2m7ChSCAWFFbLwbO0='>
    </head>
    <body>
        <div id='root' class='container'></div>

        <script type='module' src='vendor.bundle.js?t=1696156680953' integrity='sha256-y4lP6kSpQAYMK/JBVAlqd+KwJlBRwEDdNa+65dAl3KQ='></script>
        <script type='module' src='react.bundle.js?t=1696156680953' integrity='sha256-s1s4k0BQ4xzfj26zPL9hw5kmxy4LmhVKRZ2feeMRIZs='></script>
        <script type='module' src='app.bundle.js?t=1696156680953' integrity='sha256-QYKFWFQbgrGAR1kAVrVOID67fZ3igHR/Ob2XVgtI1Co='></script>
    </body>
</html>
© www.soinside.com 2019 - 2024. All rights reserved.