前端开发数据缓存方案详解
一般我们为了解决以下问题,考虑通过缓存数据来提升整体应用性能,包含:
-
频繁的网络请求会影响应用性能。
-
离线状态下无法访问数据。
-
大量数据的本地存储和快速检索需求。
常见的前端数据缓存方案有:
-
localstorage
-
indexedDB
-
service worker
1. localstorage
localStorage是 HTML5 引入的一种 Web 存储方式,它允许在浏览器中以键值对的形式存储数据。localstorage的数据存储是持久化的,即使浏览器关闭后数据也不会丢失,除非手动删除。
面试经常会被问到,用户信息存储在哪里呀?这样我们也能体会得到,localstorage的作用就是暂存一些关键数据在本地,为下次访问与使用做前置准备。
1.1. 基本用法
// 存储数据
localStorage.setItem('username', 'Alice');// 获取数据
const username = localStorage.getItem('username');
console.log(username); // 输出: Alice// 删除特定数据
localStorage.removeItem('username');// 清除所有数据
localStorage.clear();
1.2. 主要特征
-
每个域名最多可以存储5MB左右的数据。
-
数据以纯文本形式存储,主要用于存储简单的字符串类型的数据。
-
数据没有过期时间,所以需要自己实现过期时间处理或者借助后端实现。
-
数据在同域下共享。
1.3. 实际应用
1.3.1 用户偏好设置
存储用户偏好设置、主题选择等需要持久化的简单数据。
// 保存用户选择的主题
function saveThemePreference(theme) {localStorage.setItem('theme', theme);applyTheme(theme);
}// 应用用户选择的主题
function applyTheme(theme) {if (theme === 'dark') {document.body.classList.add('dark-theme');} else {document.body.classList.remove('dark-theme');}
}// 页面加载时,检查并应用存储的主题
window.onload = function() {const savedTheme = localStorage.getItem('theme');if (savedTheme) {applyTheme(savedTheme);}
};// 示例:用户选择主题
document.getElementById('themeToggle').addEventListener('click', function() {const currentTheme = document.body.classList.contains('dark-theme') ? 'light' : 'dark';saveThemePreference(currentTheme);
});
1.3.2. 表单数据缓存
存储表单数据,防止页面刷新后数据丢失。
// 实时保存表单数据
document.getElementById('userForm').addEventListener('input', function() {const formData = {name: document.getElementById('name').value,email: document.getElementById('email').value};localStorage.setItem('formData', JSON.stringify(formData));
});// 页面加载时,恢复表单数据
window.onload = function() {const savedFormData = localStorage.getItem('formData');if (savedFormData) {const formData = JSON.parse(savedFormData);document.getElementById('name').value = formData.name || '';document.getElementById('email').value = formData.email || '';}
};// 示例:用户提交表单时清除保存的数据
document.getElementById('userForm').addEventListener('submit', function() {localStorage.removeItem('formData');
});
1.3.3. 筛选数据缓存
缓存少量且不频繁变动的静态数据。
// 检查缓存是否存在静态数据
function loadCategories() {const categories = localStorage.getItem('categories');if (categories) {renderCategories(JSON.parse(categories));} else {fetchCategoriesFromServer();}
}// 从服务器获取数据并缓存
function fetchCategoriesFromServer() {fetch('/api/categories').then(response => response.json()).then(data => {localStorage.setItem('categories', JSON.stringify(data));renderCategories(data);}).catch(error => {console.error('Error fetching categories:', error);});
}// 将数据渲染到页面
function renderCategories(categories) {const categoryList = document.getElementById('categoryList');categories.forEach(category => {const listItem = document.createElement('li');listItem.textContent = category.name;categoryList.appendChild(listItem);});
}// 页面加载时调用函数
window.onload = function() {loadCategories();
};
2. indexedDB
IndexedDB 用于在用户的浏览器中存储大量的结构化数据。它是基于事务的数据库系统,可以存储大量的对象,并支持索引、检索、事务等功能。需要注意的是,IndexedDB 数据库属于非关系型数据库。
IndexedDB 是一个事务型的非关系型数据库。它是浏览器提供的本地数据库,可以被网页脚本创建和操作,允许存贮大量数据,提供查找接口,能建立索引,用于在客户端存储大量的结构化数据,也包括文件/二进制大型对象。
2.1. 基本用法
2.1.1. 打开数据库
var request = indexedDB.open('myDatabase', 1);request.onupgradeneeded = function(event) {var db = event.target.result;db.createObjectStore("myObjectStore", { keyPath: 'id' });
};request.onsuccess = function(event) {var db = event.target.result;console.log('Database opened succes