前端缓存策略:让你的网站飞起来

前端缓存策略:让你的网站飞起来

毒舌时刻

前端缓存?这不是浏览器的事吗?

"我不需要管缓存,浏览器会自动处理"——结果网站加载慢,用户体验差,
"缓存就是localStorage嘛,多简单"——结果缓存管理混乱,内存占用高,
"我直接禁用缓存,省得麻烦"——结果每次都重新加载,浪费带宽。

醒醒吧,前端缓存不是简单的localStorage,而是一套完整的策略!

为什么你需要这个?

  • 性能提升:减少重复请求,加快页面加载速度
  • 用户体验:离线访问,减少等待时间
  • 带宽节省:减少服务器流量,降低成本
  • 可靠性:网络不稳定时仍能正常访问

反面教材

// 反面教材:滥用localStorage function fetchData() { // 每次都从API获取数据 return fetch('https://api.example.com/data') .then(res => res.json()) .then(data => { // 直接存储到localStorage localStorage.setItem('data', JSON.stringify(data)); return data; }); } // 反面教材:没有缓存失效策略 function getCachedData() { // 永远使用缓存,不考虑过期 const cachedData = localStorage.getItem('data'); return cachedData ? JSON.parse(cachedData) : null; } // 反面教材:缓存键命名混乱 function cacheData(key, data) { // 缓存键没有统一规范 localStorage.setItem(`cache_${key}_${Date.now()}`, JSON.stringify(data)); } 

正确的做法

// 正确的做法:完整的缓存策略 class CacheManager { constructor() { this.cachePrefix = 'app_cache_'; this.defaultExpiry = 24 * 60 * 60 * 1000; // 24小时 } // 生成缓存键 generateKey(key) { return `${this.cachePrefix}${key}`; } // 存储数据到缓存 set(key, data, expiry = this.defaultExpiry) { const cacheItem = { data, expiry: Date.now() + expiry, timestamp: Date.now() }; try { localStorage.setItem(this.generateKey(key), JSON.stringify(cacheItem)); } catch (error) { console.error('Cache storage error:', error); // 处理存储空间不足的情况 this.clearOldCache(); } } // 从缓存获取数据 get(key) { const cacheItem = localStorage.getItem(this.generateKey(key)); if (!cacheItem) { return null; } try { const parsedItem = JSON.parse(cacheItem); // 检查是否过期 if (Date.now() > parsedItem.expiry) { this.remove(key); return null; } return parsedItem.data; } catch (error) { console.error('Cache parsing error:', error); this.remove(key); return null; } } // 移除缓存 remove(key) { localStorage.removeItem(this.generateKey(key)); } // 清空所有缓存 clear() { Object.keys(localStorage).forEach(key => { if (key.startsWith(this.cachePrefix)) { localStorage.removeItem(key); } }); } // 清理过期缓存 clearOldCache() { Object.keys(localStorage).forEach(key => { if (key.startsWith(this.cachePrefix)) { try { const item = JSON.parse(localStorage.getItem(key)); if (Date.now() > item.expiry) { localStorage.removeItem(key); } } catch (error) { localStorage.removeItem(key); } } }); } // 获取缓存大小 getCacheSize() { let size = 0; Object.keys(localStorage).forEach(key => { if (key.startsWith(this.cachePrefix)) { size += localStorage.getItem(key).length; } }); return size; } } // 正确的做法:使用Service Worker缓存 // service-worker.js const CACHE_NAME = 'app-cache-v1'; const ASSETS_TO_CACHE = [ '/', '/index.html', '/manifest.json', '/static/js/main.js', '/static/css/main.css', '/static/images/logo.png' ]; // 安装Service Worker self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME) .then(cache => { console.log('Opened cache'); return cache.addAll(ASSETS_TO_CACHE); }) ); }); // 激活Service Worker self.addEventListener('activate', event => { const cacheWhitelist = [CACHE_NAME]; event.waitUntil( caches.keys().then(cacheNames => { return Promise.all( cacheNames.map(cacheName => { if (cacheWhitelist.indexOf(cacheName) === -1) { return caches.delete(cacheName); } }) ); }) ); }); // 拦截网络请求 self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request) .then(response => { // 如果缓存中有响应,直接返回 if (response) { return response; } // 否则发起网络请求 return fetch(event.request) .then(response => { // 如果响应有效,缓存一份 if (response && response.status === 200 && response.type === 'basic') { const responseToCache = response.clone(); caches.open(CACHE_NAME) .then(cache => { cache.put(event.request, responseToCache); }); } return response; }); }) ); }); // 正确的做法:API请求缓存 async function fetchWithCache(url, options = {}) { const cacheKey = `api_${url}_${JSON.stringify(options)}`; const cacheManager = new CacheManager(); // 尝试从缓存获取 const cachedData = cacheManager.get(cacheKey); if (cachedData) { return cachedData; } // 发起网络请求 const response = await fetch(url, options); const data = await response.json(); // 缓存数据 cacheManager.set(cacheKey, data, 5 * 60 * 1000); // 5分钟过期 return data; } 

毒舌点评

看看,这才叫前端缓存策略!不是简单地使用localStorage,而是构建一套完整的缓存管理系统,包括过期策略、空间管理、Service Worker等。

记住,缓存不是越多越好,而是要合理使用。你需要根据数据的性质和使用频率,选择合适的缓存策略。

所以,别再觉得缓存是浏览器的事了,它是前端性能优化的重要组成部分!

总结

  • localStorage:适合存储小量、不敏感的数据
  • sessionStorage:适合存储会话期间的数据
  • IndexedDB:适合存储大量结构化数据
  • Service Worker:适合缓存静态资源和API响应
  • 缓存策略:合理设置过期时间,定期清理过期缓存
  • 缓存键管理:使用统一的命名规范,避免缓存键冲突
  • 错误处理:处理存储空间不足等异常情况
  • 性能监控:监控缓存命中率,不断优化缓存策略

前端缓存,让你的网站飞起来!

Read more

Element-Plus-X:基于Vue 3的AI交互组件库

Element-Plus-X:基于Vue 3的AI交互组件库 一、什么是Element-Plus-X? Element-Plus-X 是一个专门为AI应用场景设计的Vue 3组件库,可以理解为 “Element Plus的AI增强版”。它在保留Element Plus优雅设计体系的同时,深度整合了现代AI应用所需的各种交互组件。 核心定位:让前端开发者能够像搭建普通后台管理系统一样,快速构建复杂的AI交互界面。 二、核心特性:为什么选择Element-Plus-X? 2.1 专为AI设计的组件体系 Element-Plus-X提供了一系列开箱即用的AI交互组件: * 智能聊天组件:Bubble、BubbleList、Conversations * 多模态输入:Sender组件支持文本、语音、文件上传 * 状态展示:Thinking、ThoughtChain展示AI思考过程 * 辅助组件:Welcome、Prompts、FilesCard等 2.2 无缝的技术栈集成 // 与主流技术栈完美兼容 Vue 3+ TypeScript + Element Plus

AI生成图片R18提示词:新手入门指南与最佳实践

AI 生成图片 R18 提示词:新手入门指南与最佳实践 (2026 年视角,适用于本地 Stable Diffusion / Flux / Pony 等开源模型,或部分支持 NSFW 的在线平台) R18(成人限制级)内容在 AI 图像生成中属于高敏感领域,不同模型/平台对它的开放程度差异极大: * 完全封禁或强过滤:Midjourney、DALL·E 3/4、Flux.1 [dev/pro] 官方、Google Imagen、Adobe Firefly 等 * 部分支持但需技巧:NovelAI、Pony Diffusion、Flux Uncensored 变体、某些 SDXL LoRA 模型

AI如何帮你快速找到JXX登录网页最新域名

快速体验 1. 打开 InsCode(快马)平台 https://www.inscode.net 2. 输入框内输入如下内容: 开发一个智能域名追踪系统,能够自动检测JXX登录网页的最新域名变更。系统需要包含以下功能:1. 定时爬取JXX相关页面,检测域名变化;2. 通过DNS解析验证域名有效性;3. 发现新域名后自动通知用户;4. 提供历史域名记录查询。使用Python实现,集成requests库进行网页请求,dnspython库进行DNS解析,并添加邮件通知功能。 1. 点击'项目生成'按钮,等待项目生成完整后预览效果 AI如何帮你快速找到JXX登录网页最新域名 最近在做一个需要频繁访问JXX网站的项目,但发现这个网站的登录域名经常变更,每次都要花时间到处找最新地址,特别影响工作效率。于是研究了下如何用AI辅助开发一个智能域名追踪系统,自动帮我解决这个问题。 系统设计思路 1. 定时爬取检测:系统需要定期自动访问JXX相关页面,检查是否有新域名出现。这里用Python的requests库就能实现,设置合理的请求间隔避免被封禁。 2.

AI 驱动游戏:鸿蒙生态的机会在哪里?

AI 驱动游戏:鸿蒙生态的机会在哪里?

子玥酱(掘金 / 知乎 / ZEEKLOG / 简书 同名) 大家好,我是子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。 我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括前端工程化、小程序、React / RN、Flutter、跨端方案, 在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。 技术方向:前端 / 跨端 / 小程序 / 移动端工程化 内容平台:掘金、知乎、ZEEKLOG、简书 创作特点:实战导向、源码拆解、少空谈多落地 文章状态:长期稳定更新,大量原创输出 我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、