mfl*_*din 4 javascript caching reactjs remix.run
我需要从一个非常慢且很少变化的 API 获取数据,所以我想我应该使用内存缓存。我首先尝试了一种非常简单的方法,只需将其保存到路径中加载器函数范围之外的变量中:
let cache;
export const loader = async () => {
if (!cache) {
// we always end up here
cache = await (await fetch("...)).json()
}
}
Run Code Online (Sandbox Code Playgroud)
但这没有用。然后我尝试了一个适当的缓存库(lru-cache),但该缓存也始终是空的。然后我意识到整个文件在每个请求上都会重新加载,我猜这是开发模式的事情,所以我尝试将缓存的创建移动到一个单独的文件cache.server.ts并从那里导入它。
import LRU from "lru-cache";
console.log("Creating cache"); // this is logged on each request
const cache = new LRU({ max: 200 });
export default cache;
Run Code Online (Sandbox Code Playgroud)
但该文件似乎也会根据每个请求重新加载。
如果我构建一个生产版本并运行一切都很好,但如果有某种方法让它在开发模式下工作也很好。
Remix 会清除require开发中每个请求的缓存以支持<LiveReload/>. 为了确保您的缓存在这些清除中幸存下来,您需要将其分配给global对象。
编辑:这是处理这个问题的更好方法
// utils/singleton.server.ts
// since the dev server re-requires the bundle, do some shenanigans to make
// certain things persist across that
// Borrowed/modified from https://github.com/jenseng/abuse-the-platform/blob/2993a7e846c95ace693ce61626fa072174c8d9c7/app/utils/singleton.ts
export function singleton<Value>(name: string, value: () => Value): Value {
const yolo = global as any
yolo.__singletons ??= {}
yolo.__singletons[name] ??= value()
return yolo.__singletons[name]
}
Run Code Online (Sandbox Code Playgroud)
// utils/prisma.server.ts
import { PrismaClient } from '@prisma/client'
import { singleton } from './singleton.server.ts'
const prisma = singleton('prisma', () => new PrismaClient())
prisma.$connect()
export { prisma }
Run Code Online (Sandbox Code Playgroud)
作为Kilimans 回答的后续,我是这样做的:
/*
* @see https://www.npmjs.com/package/node-cache
*/
import NodeCache from "node-cache";
let cache: NodeCache;
declare global {
var __cache: NodeCache | undefined;
}
if (process.env.NODE_ENV === "production") {
cache = new NodeCache();
} else {
if (!global.__cache) {
global.__cache = new NodeCache();
}
cache = global.__cache;
}
export { cache };
Run Code Online (Sandbox Code Playgroud)
我在加载器中使用了它:
import { getGitHubRepos } from "~/models/github.server";
import { cache } from "~/utils/cache";
export async function loader(args: LoaderArgs) {
if (cache.has("GitHubRepos")) {
return json(cache.get("GitHubRepos"));
}
const repos = await getGitHubRepos();
cache.set("GitHubRepos", repos, 60 * 60 * 24);
return json(repos);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3594 次 |
| 最近记录: |