diff --git a/packages/app/package.json b/packages/app/package.json index 576cec3d..46515828 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -40,6 +40,7 @@ "react-textarea-autosize": "^8.4.0", "recharts": "^2.8.0", "three": "^0.157.0", + "typescript-lru-cache": "^2.0.0", "use-long-press": "^3.2.0", "use-sync-external-store": "^1.2.0", "uuid": "^9.0.0", diff --git a/packages/app/src/Components/Embed/LinkPreview.tsx b/packages/app/src/Components/Embed/LinkPreview.tsx index 89913da2..e00fdfa2 100644 --- a/packages/app/src/Components/Embed/LinkPreview.tsx +++ b/packages/app/src/Components/Embed/LinkPreview.tsx @@ -1,6 +1,7 @@ import "./LinkPreview.css"; import { CSSProperties, useEffect, useState } from "react"; +import { LRUCache } from 'typescript-lru-cache'; import { MediaElement } from "@/Components/Embed/MediaElement"; import Spinner from "@/Components/Icons/Spinner"; @@ -16,18 +17,24 @@ async function fetchUrlPreviewInfo(url: string) { } } +const cache = new LRUCache({ + maxSize: 100, +}); + const LinkPreview = ({ url }: { url: string }) => { - const [preview, setPreview] = useState(); + const [preview, setPreview] = useState(cache.get(url)); const { proxy } = useImgProxy(); useEffect(() => { (async () => { + if (preview) return; const data = await fetchUrlPreviewInfo(url); if (data) { const type = data.og_tags?.find(a => a[0].toLowerCase() === "og:type"); const canPreviewType = type?.[1].startsWith("image") || type?.[1].startsWith("video") || false; if (canPreviewType || data.image) { setPreview(data); + cache.set(url, data); return; } } diff --git a/yarn.lock b/yarn.lock index 7f318915..b604b739 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2994,6 +2994,7 @@ __metadata: three: ^0.157.0 tinybench: ^2.5.1 typescript: ^5.2.2 + typescript-lru-cache: ^2.0.0 use-long-press: ^3.2.0 use-sync-external-store: ^1.2.0 uuid: ^9.0.0 @@ -11290,6 +11291,13 @@ __metadata: languageName: node linkType: hard +"typescript-lru-cache@npm:^2.0.0": + version: 2.0.0 + resolution: "typescript-lru-cache@npm:2.0.0" + checksum: 50948bb62cfe928f0baf4dcc09634cc2456520c0abf2ad726483039371eb523ee6b9c4f45210704f3c1fb30dc6ae5e5ffb27127a34d626848db9d80bcb3057d1 + languageName: node + linkType: hard + "typescript@npm:5, typescript@npm:^5.2.2": version: 5.2.2 resolution: "typescript@npm:5.2.2"