You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 06:55:33