SvelteKit中如何在+page.server.js与+server.js间共享数据
在SvelteKit中共享+page.server.js与+server.js的数据
当前场景与问题
- 在
+page.server.js的load函数中从数据库拉取全量用户数据,完整返回给浏览器 - 前端在内存中实现跨字段元搜索,小数据集下仅轻微延迟,但数据量增长后会引发严重性能问题
你的解决方案思路
- 保留
+page.server.js的load函数加载数据,让+server.js的GET函数能访问这份数据集 - 用户输入搜索词时,请求
+server.js,在服务端完成过滤后返回结果,替代前端内存过滤逻辑
可行实现方法
1. 服务器端全局缓存(适合静态/低频更新数据)
可以用内存缓存库(比如lru-cache)做全局缓存,让两个文件共享数据:
// 新建共享缓存模块:lib/userCache.js import LRU from 'lru-cache'; export const userCache = new LRU({ max: 1, ttl: 60 * 1000 }); // 缓存1分钟,最多存1份数据 // +page.server.js import { userCache } from '$lib/userCache'; import db from '$lib/db'; export async function load() { const users = await db.query('SELECT * FROM users'); userCache.set('users', users); // 可选:只返回少量初始数据给前端,减少首次加载体积 return { initialUsers: users.slice(0, 20) }; } // +server.js import { userCache } from '$lib/userCache'; import db from '$lib/db'; export async function GET({ url }) { const query = url.searchParams.get('q')?.toLowerCase() || ''; // 先从缓存取,取不到就查数据库并更新缓存 let users = userCache.get('users'); if (!users) { users = await db.query('SELECT * FROM users'); userCache.set('users', users); } // 服务端过滤逻辑 const filtered = users.filter(user => Object.values(user).some(val => val?.toString().toLowerCase().includes(query)) ); return new Response(JSON.stringify(filtered), { headers: { 'Content-Type': 'application/json' } }); }
- 注意:全局缓存是服务器级别的,所有用户共享,不适合需要用户隔离的数据;缓存过期时间可根据数据更新频率调整。
2. 抽离数据加载逻辑为独立模块
把数据库查询逻辑单独封装,利用Node.js的模块缓存特性实现数据共享:
// 抽离模块:lib/userData.js import db from '$lib/db'; let cachedUsers = null; export async function getUsers() { if (!cachedUsers) { cachedUsers = await db.query('SELECT * FROM users'); } return cachedUsers; } // 可选:添加刷新缓存的方法 export async function refreshUsers() { cachedUsers = await db.query('SELECT * FROM users'); return cachedUsers; } // +page.server.js import { getUsers } from '$lib/userData'; export async function load() { const users = await getUsers(); return { initialUsers: users.slice(0, 20) }; } // +server.js import { getUsers } from '$lib/userData'; export async function GET({ url }) { const query = url.searchParams.get('q')?.toLowerCase() || ''; const users = await getUsers(); const filtered = users.filter(user => Object.values(user).some(val => val?.toString().toLowerCase().includes(query)) ); return new Response(JSON.stringify(filtered), { headers: { 'Content-Type': 'application/json' } }); }
- 模块缓存会在服务器启动后一直保留,直到服务器重启或调用刷新方法;适合数据更新不频繁的场景。
3. 直接在+server.js中做数据库查询过滤(最优解,推荐)
如果数据更新频繁,或者数据集本身很大,没必要在服务端存全量数据,直接让+server.js根据搜索词做数据库查询——数据库的索引优化比内存过滤效率高得多:
// +server.js import db from '$lib/db'; export async function GET({ url }) { const query = url.searchParams.get('q') || ''; // 用数据库模糊查询替代内存过滤,可根据实际字段调整 const filteredUsers = await db.query(` SELECT * FROM users WHERE name LIKE ? OR email LIKE ? OR phone LIKE ? `, [`%${query}%`, `%${query}%`, `%${query}%`]); return new Response(JSON.stringify(filteredUsers), { headers: { 'Content-Type': 'application/json' } }); }
- 这种方法不需要共享数据,避免了服务端内存占用问题,同时利用数据库的查询优化,大数据量下性能更优。
内容的提问来源于stack exchange,提问作者Shakir
相关产品推荐
相关产品推荐

