From 89a500cd3e17622c7181106f8f4b7c140caa9845 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Thu, 7 May 2026 23:06:27 +0700 Subject: [PATCH] perf(website): avoid blocking root render on GitHub --- packages/website/src/release.ts | 44 ++++++++++++++++++++++++--------- packages/website/src/stars.ts | 28 +++++++++++++++++++-- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/packages/website/src/release.ts b/packages/website/src/release.ts index 1ecb8c801..79b681c6f 100644 --- a/packages/website/src/release.ts +++ b/packages/website/src/release.ts @@ -49,16 +49,20 @@ interface ReleaseInfo { windowsArm64Asset: string | null; } +const fallbackVersion = websitePackage.version.replace(/-.*$/, ""); +const fallbackRelease: ReleaseInfo = { + version: fallbackVersion, + windowsX64Asset: `Paseo-Setup-${fallbackVersion}.exe`, + windowsArm64Asset: null, +}; const GITHUB_RELEASES_URL = "https://api.github.com/repos/getpaseo/paseo/releases?per_page=10"; +const RELEASE_REFRESH_MS = 60_000; + +let cachedRelease = fallbackRelease; +let cachedReleaseAt = 0; +let refreshReleasePromise: Promise | null = null; async function fetchLatestReadyRelease(): Promise { - const fallbackVersion = websitePackage.version.replace(/-.*$/, ""); - const fallback: ReleaseInfo = { - version: fallbackVersion, - windowsX64Asset: `Paseo-Setup-${fallbackVersion}.exe`, - windowsArm64Asset: null, - }; - try { const res = await fetch(GITHUB_RELEASES_URL, { headers: { @@ -74,11 +78,11 @@ async function fetchLatestReadyRelease(): Promise { cacheKey: "github-releases-latest", }, } as RequestInit); - if (!res.ok) return fallback; + if (!res.ok) return fallbackRelease; const releases = (await res.json()) as GitHubRelease[]; const ready = releases.find((r) => !r.prerelease && !r.draft && hasRequiredAssets(r)); - if (!ready) return fallback; + if (!ready) return fallbackRelease; const win = pickWindowsAssets(ready.assets); return { version: versionFromTag(ready.tag_name), @@ -86,10 +90,28 @@ async function fetchLatestReadyRelease(): Promise { windowsArm64Asset: win.arm64, }; } catch { - return fallback; + return fallbackRelease; } } +function refreshLatestRelease(): Promise { + refreshReleasePromise ??= fetchLatestReadyRelease() + .then((release) => { + cachedRelease = release; + cachedReleaseAt = Date.now(); + return undefined; + }) + .finally(() => { + refreshReleasePromise = null; + }); + + return refreshReleasePromise; +} + export const getLatestRelease = createServerFn({ method: "GET" }).handler(async () => { - return fetchLatestReadyRelease(); + if (Date.now() - cachedReleaseAt > RELEASE_REFRESH_MS) { + void refreshLatestRelease(); + } + + return cachedRelease; }); diff --git a/packages/website/src/stars.ts b/packages/website/src/stars.ts index cf5775e07..f441c24f4 100644 --- a/packages/website/src/stars.ts +++ b/packages/website/src/stars.ts @@ -11,6 +11,11 @@ function formatStars(count: number): string { } const GITHUB_REPO_URL = "https://api.github.com/repos/getpaseo/paseo"; +const STAR_REFRESH_MS = 60_000; + +let cachedStars = ""; +let cachedStarsAt = 0; +let refreshStarsPromise: Promise | null = null; async function fetchStarCount(): Promise { try { @@ -34,7 +39,26 @@ async function fetchStarCount(): Promise { } } +function refreshStarCount(): Promise { + refreshStarsPromise ??= fetchStarCount() + .then((stars) => { + if (stars) { + cachedStars = stars; + cachedStarsAt = Date.now(); + } + return undefined; + }) + .finally(() => { + refreshStarsPromise = null; + }); + + return refreshStarsPromise; +} + export const getStarCount = createServerFn({ method: "GET" }).handler(async () => { - const stars = await fetchStarCount(); - return { stars }; + if (Date.now() - cachedStarsAt > STAR_REFRESH_MS) { + void refreshStarCount(); + } + + return { stars: cachedStars }; });