【Web 应用缓存与部署优化指南】

Web 应用缓存与部署优化指南

目录

  1. [HTTP 缓存机制](#HTTP 缓存机制)
  2. 浏览器缓存体系
  3. [Cache Storage API](#Cache Storage API)
  4. 构建与部署优化
  5. 环境特定策略
  6. 问题诊断与解决方案

HTTP 缓存机制

强缓存

浏览器直接使用本地缓存,不与服务器通信。

控制头部

http 复制代码
Cache-Control: max-age=31536000
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: must-revalidate
Expires: Wed, 12 Jun 2026 12:00:00 GMT

特点

  • 命中强缓存时不发送请求
  • 通过 DevTools 可见 200 (from disk cache)200 (from memory cache)
  • 适用于带版本号的静态资源

协商缓存

浏览器与服务器协商验证资源是否更新。

控制头部

http 复制代码
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Last-Modified: Wed, 12 Jun 2024 12:00:00 GMT
If-Modified-Since: Wed, 12 Jun 2024 12:00:00 GMT

特点

  • 每次都发送请求验证
  • 资源未变时返回 304 状态码
  • 适用于 HTML 等经常变化的资源

浏览器缓存体系

缓存位置

  1. Service Worker Cache
  2. Memory Cache
  3. Disk Cache
  4. Push Cache (HTTP/2)

缓存优先级

  1. Service Worker 的 Cache Storage
  2. Memory Cache(内存缓存)
  3. Disk Cache(磁盘缓存)
  4. 网络请求

Cache Storage API

基本概念

Cache Storage API 是现代浏览器提供的可编程缓存接口。

使用场景

  • Service Worker 中
  • Window 上下文(普通网页)
  • Worker 上下文

权限与安全

  1. 访问限制

    • 仅能访问同源的 Cache Storage
    • 无法访问浏览器的 HTTP 缓存
    • 无法访问其他存储机制
  2. 控制台访问

    • 可以在 DevTools 中查看和操作
    • 仅限当前网站的缓存
    • 遵循同源策略

基本用法

javascript 复制代码
// 打开缓存
const cache = await caches.open('v1');

// 存储响应
await cache.put('/api/data', response);

// 读取缓存
const cached = await cache.match('/api/data');

// 删除缓存
await cache.delete('/api/data');

// 清理所有缓存
const keys = await caches.keys();
await Promise.all(keys.map(key => caches.delete(key)));

构建与部署优化

1. Webpack 配置优化

javascript 复制代码
module.exports = {
  output: {
    filename: '[name].[contenthash:8].js',
    chunkFilename: '[name].[contenthash:8].chunk.js',
    clean: true  // 清理 dist 目录
  },
  optimization: {
    moduleIds: 'deterministic',  // 确保模块 ID 稳定
    runtimeChunk: 'single',      // 分离 runtime 代码
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all',
        },
      }
    }
  }
}

2. 服务器配置

nginx 复制代码
# HTML - 协商缓存
location / {
    try_files $uri $uri/ /index.html;
    add_header Cache-Control "no-cache";
    etag on;
}

# 静态资源 - 长期缓存
location /static/ {
    add_header Cache-Control "public, max-age=31536000, immutable";
}

# 动态 chunks - 长期缓存
location /chunks/ {
    add_header Cache-Control "public, max-age=31536000, immutable";
}

3. 版本控制系统

javascript 复制代码
// webpack 注入版本信息
new webpack.DefinePlugin({
    'process.env.APP_VERSION': JSON.stringify(require('./package.json').version),
    'process.env.BUILD_TIME': JSON.stringify(new Date().toISOString())
})

class VersionManager {
    async checkUpdate() {
        const response = await fetch('/version.json', {
            headers: { 'Cache-Control': 'no-cache' }
        });
        const { version, buildTime } = await response.json();
        
        if (version !== process.env.APP_VERSION || 
            buildTime !== process.env.BUILD_TIME) {
            await this.handleUpdate();
        }
    }

    async handleUpdate() {
        await this.clearCaches();
        if (confirm('发现新版本,是否刷新?')) {
            window.location.reload(true);
        }
    }
}

4. 部署流程

bash 复制代码
#!/bin/bash
VERSION=$(date +%Y%m%d%H%M%S)
DEPLOY_DIR="/usr/share/nginx/html"

# 1. 新建版本目录
mkdir -p ${DEPLOY_DIR}/${VERSION}

# 2. 部署新文件
cp -r dist/* ${DEPLOY_DIR}/${VERSION}/

# 3. 切换版本
ln -sfn ${DEPLOY_DIR}/${VERSION} ${DEPLOY_DIR}/current

# 4. 保留最近版本
ls -dt ${DEPLOY_DIR}/20* | tail -n +4 | xargs rm -rf

环境特定策略

开发环境

nginx 复制代码
# 开发环境配置
location / {
    add_header Cache-Control "no-store";
    add_header Pragma no-cache;
}

特点

  • 禁用缓存
  • 启用热更新
  • 频繁版本检查

测试环境

nginx 复制代码
# 测试环境配置
location / {
    add_header Cache-Control "no-cache";
    etag on;
    if_modified_since exact;
}

特点

  • 短期缓存
  • 版本检测
  • 强制刷新功能

生产环境

策略

  • HTML:协商缓存
  • JS/CSS:contenthash + 长期缓存
  • 图片/字体:hash + 长期缓存
  • API:按数据特性决定

问题诊断与解决方案

1. 缓存不一致

症状

  • 新旧代码混合
  • 功能异常
  • 样式错乱

解决方案

  1. 确保资源使用 contenthash
  2. 实施"先静态资源,后 HTML"的部署顺序
  3. 实现版本检测机制

2. CDN 缓存问题

症状

  • 不同地区用户体验不一致
  • 更新不同步

解决方案

  1. 使用版本化 URL
  2. 配置合适的缓存刷新策略
  3. 实施灰度发布

3. 测试环境缓存

症状

  • 测试结果不准确
  • 需要频繁强制刷新

解决方案

  1. 配置 no-store 头部
  2. 使用版本检测
  3. 提供一键刷新功能

最佳实践总结

1. 资源分类策略

  • HTML:协商缓存
  • JS/CSS:contenthash + 长期缓存
  • 图片/字体:hash + 长期缓存
  • API:按数据时效性决定

2. 构建优化

  • 使用 contenthash
  • 合理代码分割
  • 提取公共依赖

3. 部署流程

  • 版本化部署
  • 支持快速回滚
  • 自动化发布

4. 监控维护

  • 监控缓存命中率
  • 观察版本更新效果
  • 及时处理缓存问题

记住:缓存策略不仅是技术选择,更是产品需求、用户体验和运维效率的平衡。好的缓存策略应该:

  • 保证资源更新的及时性
  • 最大化缓存利用率
  • 支持快速问题诊断
  • 便于运维和回滚
相关推荐
乘风gg2 分钟前
还在养虾吗?虾王已诞生:微信龙虾 ClawBot
前端·ai编程·claude
小小小小宇17 分钟前
LLM 长期记忆构建
前端
lichenyang45329 分钟前
从 Express 老项目到 NestJS + Docker:一次车辆管理系统的渐进式重构
前端
Momo__2 小时前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
程序员小富2 小时前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇2 小时前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇2 小时前
React中的forwardRef
前端·react.js·面试
槑有老呆2 小时前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马2 小时前
Verilog开发常见问题汇总解析
前端
子兮曰2 小时前
AI Coding Method Map:一张图看懂 AI 编程的完整链路
前端·人工智能·后端