aurora blog
  • JS

    • 基本汇总
    • Date时间
    • Array方法
    • String 方法
    • Object方法
    • RegExp正则
    • Es6 新特性等
    • Event-Loop
    • Http and Https
    • for in和for of区别
    • Web Worker
    • Promise && async
    • 堆内存 & 栈内存
    • JS设计模式探索
    • npm & yarn
    • Fetch和Axios的区别
    • 学习及面试问题整理
    • URL 输入到页面加载过程
    • 跨域&nginx本地项目代理
  • FE框架

    • react

      • 基本用法
      • react生命周期
      • hooks 16.8版本后
      • Route原理
      • Redux源码解析
      • React16 Fiber
      • React-VirtualDOM
      • React事件委托机制
      • React性能优化
      • 状态管理方案对比
      • React 18新特性
    • vue

      • vue 基本用法
      • vue 生命周期
      • VirtualDOM
      • vue 事件委托
      • vue 架构
      • vue 状态管理
      • 问题等
    • React-Native

      • React-Native 基本用法
    • 微前端

      • 遇到的问题
    • 鸿蒙 harmony

      • harmony 基础
  • 构建工具

    • webpack

      • Webpack配置详解
      • Webpack的使用
      • Babel-polyfill
      • webpack面试题
    • vite

      • vite配置详解
      • vite面试题
    • rollup

      • Rollup配置详解
      • rollup面试题
    • 构建工具对比
  • 性能优化

    • 性能优化策略
    • 缓存策略
    • 性能优化面试题
  • 浏览器

    • 浏览器渲染原理
    • 浏览器缓存机制
    • 浏览器面试题
  • 工程化

    • 代码规范
    • 工程化面试题
  • 前端安全

    • XSS 攻击与防护
    • CSRF 攻击与防护
    • 前端安全面试题
  • 移动端开发

    • 移动端适配
    • 移动端开发面试题
  • 前端监控

    • 错误监控
    • 性能监控
    • 前端监控面试题
  • Typescript

    • Typescript详解
  • Servers

    • Nodejs
    • Nginx
  • Git命令

    • git常用规范
  • 数据库

    • mongodb
    • mongodb
  • Other

    • Jenkins自动化部署

浏览器缓存机制

  • 缓存概述
  • HTTP 缓存
    • 1. 强缓存
    • 2. 协商缓存
    • 3. 缓存策略
  • 浏览器存储
    • 1. Cookie
    • 2. LocalStorage
    • 3. SessionStorage
    • 4. IndexedDB
  • Service Worker 缓存
    • 缓存策略
  • 缓存最佳实践
    • 1. 选择合适的存储方式
    • 2. 缓存版本控制
    • 3. 缓存更新策略
  • 常见问题
    • 1. 缓存不生效
    • 2. Cookie 安全问题
    • 3. 存储空间限制
    • 4. 跨域存储

缓存概述

浏览器缓存是提升性能的重要手段,主要包括:

  • HTTP 缓存:强缓存、协商缓存
  • 浏览器存储:Cookie、LocalStorage、SessionStorage、IndexedDB
  • Service Worker 缓存:可编程缓存

HTTP 缓存

1. 强缓存

Cache-Control:

Cache-Control: max-age=3600
Cache-Control: public, max-age=3600
Cache-Control: private, max-age=3600
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: must-revalidate

常用指令:

  • max-age:缓存有效期(秒)
  • public:可以被任何缓存存储
  • private:只能被浏览器缓存
  • no-cache:需要验证缓存
  • no-store:不缓存
  • must-revalidate:过期后必须验证
  • immutable:资源不会改变

Expires:

Expires: Wed, 21 Oct 2025 07:28:00 GMT

优先级: Cache-Control > Expires

流程:

1. 检查 Cache-Control/Expires
2. 未过期 → 使用缓存(200 from cache)
3. 已过期 → 进入协商缓存

2. 协商缓存

ETag / If-None-Match:

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Last-Modified / If-Modified-Since:

Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT

优先级: ETag > Last-Modified

流程:

1. 发送请求,携带 If-None-Match / If-Modified-Since
2. 服务器比较
3. 未改变 → 304 Not Modified(使用缓存)
4. 已改变 → 200 OK(返回新资源)

3. 缓存策略

静态资源(长期缓存):

Cache-Control: public, max-age=31536000, immutable

HTML(不缓存或短缓存):

Cache-Control: no-cache
# 或
Cache-Control: max-age=0, must-revalidate

API 响应(短缓存):

Cache-Control: private, max-age=300

浏览器存储

1. Cookie

特点:

  • 大小限制:4KB
  • 每次请求都会携带
  • 可以设置过期时间
  • 可以设置域名、路径

使用:

// 设置
document.cookie = "name=value; expires=Wed, 21 Oct 2025 07:28:00 GMT; path=/";

// 读取
const cookies = document.cookie.split(';');

// 删除(设置过期时间为过去)
document.cookie = "name=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";

属性:

  • expires:过期时间
  • max-age:有效期(秒)
  • domain:域名
  • path:路径
  • secure:只在 HTTPS 下传输
  • httpOnly:禁止 JS 访问(防 XSS)
  • sameSite:跨站请求限制

2. LocalStorage

特点:

  • 大小限制:5-10MB
  • 持久化存储
  • 同源策略
  • 同步 API

使用:

// 设置
localStorage.setItem('key', 'value');

// 读取
const value = localStorage.getItem('key');

// 删除
localStorage.removeItem('key');

// 清空
localStorage.clear();

// 获取所有 key
const keys = Object.keys(localStorage);

事件:

window.addEventListener('storage', (e) => {
  console.log(e.key);      // 改变的 key
  console.log(e.oldValue); // 旧值
  console.log(e.newValue); // 新值
  console.log(e.url);      // 改变的页面 URL
});

3. SessionStorage

特点:

  • 大小限制:5-10MB
  • 会话级别存储
  • 关闭标签页清除
  • 同源策略

使用:

// 与 LocalStorage API 相同
sessionStorage.setItem('key', 'value');
sessionStorage.getItem('key');
sessionStorage.removeItem('key');
sessionStorage.clear();

区别:

  • LocalStorage:持久化,关闭浏览器不消失
  • SessionStorage:会话级别,关闭标签页清除

4. IndexedDB

特点:

  • 大小限制:较大(通常 50MB+)
  • 异步 API
  • 支持复杂数据结构
  • 支持事务

使用:

// 打开数据库
const request = indexedDB.open('myDB', 1);

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  const objectStore = db.createObjectStore('users', { keyPath: 'id' });
  objectStore.createIndex('name', 'name', { unique: false });
};

request.onsuccess = (event) => {
  const db = event.target.result;
  
  // 添加数据
  const transaction = db.transaction(['users'], 'readwrite');
  const objectStore = transaction.objectStore('users');
  objectStore.add({ id: 1, name: 'John' });
  
  // 读取数据
  const getRequest = objectStore.get(1);
  getRequest.onsuccess = (event) => {
    console.log(event.target.result);
  };
};

Service Worker 缓存

缓存策略

Cache First:

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(response => {
      return response || fetch(event.request).then(response => {
        const responseClone = response.clone();
        caches.open('v1').then(cache => {
          cache.put(event.request, responseClone);
        });
        return response;
      });
    })
  );
});

Network First:

self.addEventListener('fetch', event => {
  event.respondWith(
    fetch(event.request).catch(() => {
      return caches.match(event.request);
    })
  );
});

Stale While Revalidate:

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.open('v1').then(cache => {
      return cache.match(event.request).then(response => {
        const fetchPromise = fetch(event.request).then(networkResponse => {
          cache.put(event.request, networkResponse.clone());
          return networkResponse;
        });
        return response || fetchPromise;
      });
    })
  );
});

缓存最佳实践

1. 选择合适的存储方式

数据类型推荐存储原因
用户登录信息Cookie(httpOnly)安全性高
用户偏好设置LocalStorage持久化
临时数据SessionStorage会话级别
大量结构化数据IndexedDB容量大、支持查询
静态资源HTTP 缓存性能好
离线资源Service Worker可编程

2. 缓存版本控制

文件名版本号:

// webpack
output: {
  filename: '[name].[contenthash:8].js',
}

查询参数版本号:

<link rel="stylesheet" href="style.css?v=1.0.0" />

3. 缓存更新策略

强制更新:

// 添加版本号或时间戳
const url = `/api/data?v=${Date.now()}`;

Service Worker 更新:

navigator.serviceWorker.register('/sw.js').then(registration => {
  registration.addEventListener('updatefound', () => {
    const newWorker = registration.installing;
    newWorker.addEventListener('statechange', () => {
      if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
        // 新版本可用
      }
    });
  });
});

常见问题

1. 缓存不生效

原因:

  • Cache-Control 配置错误
  • 文件名没有版本号
  • 浏览器禁用缓存

解决:

  • 检查 HTTP 响应头
  • 使用版本号或 hash
  • 清除浏览器缓存测试

2. Cookie 安全问题

最佳实践:

// 设置安全 Cookie
document.cookie = "name=value; secure; httpOnly; sameSite=strict";

3. 存储空间限制

处理:

  • 限制存储大小
  • 定期清理过期数据
  • 使用 LRU 策略

4. 跨域存储

限制:

  • 同源策略限制
  • 无法跨域访问

解决:

  • 使用 postMessage 通信
  • 使用 SharedArrayBuffer(需要特殊配置)
最近更新:: 2025/11/20 14:50
Contributors: liyulai
Prev
浏览器渲染原理
Next
浏览器面试题