
在共享主机环境下,通过 localstorage 或 indexeddb 缓存题目与用户答案、延迟提交,可显著降低数据库压力;但面对 2000 并发用户,需结合服务端缓存(如 redis)与更健壮的客户端存储方案以保障可靠性与扩展性。
在共享主机环境下,通过 localstorage 或 indexeddb 缓存题目与用户答案、延迟提交,可显著降低数据库压力;但面对 2000 并发用户,需结合服务端缓存(如 redis)与更健壮的客户端存储方案以保障可靠性与扩展性。
构建高性能在线测验应用时,合理分担数据处理责任至关重要——尤其当部署在资源受限的共享主机上。单纯依赖 localStorage 存储题目和用户答案虽简单易行,但存在明显局限:它仅支持字符串键值对,容量通常限于 5–10 MB,且无事务、无索引、不支持异步操作,在多步骤答题、中途刷新或网络中断场景下易丢失数据。例如:
// ❌ 不推荐:localStorage 存储复杂结构需手动序列化,缺乏容错机制
const quizData = {
questions: [...],
answers: {},
timestamp: Date.now()
};
localStorage.setItem('quiz_session', JSON.stringify(quizData));✅ 更优解是采用 IndexedDB:它是浏览器原生支持的异步、事务型 NoSQL 数据库,适合存储结构化数据(如题目列表、用户作答记录、时间戳、状态标记等),并天然支持大容量(通常达数百 MB)、索引查询与错误恢复。以下为轻量级封装示例:
// 初始化 QuizDB
const QuizDB = {
open() {
return indexedDB.open('QuizDB', 1).then(db => {
if (db.oldVersion === 0) {
const store = db.createObjectStore('sessions', { keyPath: 'id' });
store.createIndex('updatedAt', 'updatedAt');
}
return db;
});
},
saveSession(data) {
return this.open().then(db => {
const tx = db.transaction('sessions', 'readwrite');
const store = tx.objectStore('sessions');
return store.put({
id: 'current',
...data,
updatedAt: Date.now()
});
});
},
loadSession() {
return this.open().then(db => {
const tx = db.transaction('sessions', 'readonly');
const store = tx.objectStore('sessions');
return store.get('current');
});
}
};
// 使用示例
QuizDB.saveSession({
questions: [{ id: 1, text: "What is 2+2?" }],
answers: { 1: "4" },
status: "in-progress"
});⚠️ 注意事项:
- 不要完全跳过服务端验证:客户端存储仅用于优化体验与减轻瞬时压力,最终提交时仍须校验题目完整性、防篡改(如签名/哈希比对)及答案合法性;
- 设置合理的同步策略:可在用户切换题、停留超时(如 60s)或页面卸载前自动保存,避免单点故障;
- 共享主机限制:若无法部署 Redis,可退而求其次使用 PHP 文件缓存或轻量级 SQLite 作为服务端临时缓冲层;
- 并发安全:IndexedDB 的事务机制能防止多标签/窗口冲突,但需避免跨实例直接共享连接。
综上,针对 2000 并发用户的测验场景,推荐「IndexedDB + 节流提交 + 服务端缓存兜底」三层架构:前端持久化保障用户体验与离线能力,后端缓存(如 Redis)暂存批量结果并异步落库,既规避共享主机的 I/O 瓶颈,又为未来迁移至 VPS 或云服务预留平滑升级路径。

















