perf(server): aggressively cache OG image assets in memory to prevent synchronous file I/O from blocking the Node event loop
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 29s
Build & Deploy / 🧪 QA (push) Successful in 1m53s
Build & Deploy / 🏗️ Build (push) Successful in 3m25s
Build & Deploy / 🚀 Deploy (push) Successful in 36s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m14s
Build & Deploy / 🔔 Notify (push) Successful in 3s

This commit is contained in:
2026-06-30 23:02:12 +02:00
parent 4f46825fb4
commit b2701d6bcd
2 changed files with 13 additions and 4 deletions

View File

@@ -5,7 +5,9 @@ import { join } from 'path';
* Loads the Inter fonts for use in Satori (Next.js OG Image generation). * Loads the Inter fonts for use in Satori (Next.js OG Image generation).
* Since we are using runtime = 'nodejs', we can read them from the filesystem. * Since we are using runtime = 'nodejs', we can read them from the filesystem.
*/ */
let cachedFonts: any[] | null = null;
export async function getOgFonts() { export async function getOgFonts() {
if (cachedFonts) return cachedFonts;
const boldFontPath = join(process.cwd(), 'public/fonts/Inter-Bold.woff'); const boldFontPath = join(process.cwd(), 'public/fonts/Inter-Bold.woff');
const regularFontPath = join(process.cwd(), 'public/fonts/Inter-Regular.woff'); const regularFontPath = join(process.cwd(), 'public/fonts/Inter-Regular.woff');
@@ -28,7 +30,7 @@ export async function getOgFonts() {
`[OG] Fonts loaded successfully (${boldFont.byteLength} and ${regularFont.byteLength} bytes)`, `[OG] Fonts loaded successfully (${boldFont.byteLength} and ${regularFont.byteLength} bytes)`,
); );
return [ cachedFonts = [
{ {
name: 'Inter', name: 'Inter',
data: boldFont, data: boldFont,
@@ -42,28 +44,35 @@ export async function getOgFonts() {
style: 'normal' as const, style: 'normal' as const,
}, },
]; ];
return cachedFonts;
} catch (error) { } catch (error) {
console.error(`[OG] Failed to load fonts from ${process.cwd()}:`, error); console.error(`[OG] Failed to load fonts from ${process.cwd()}:`, error);
return []; return [];
} }
} }
let cachedBackground: string | null = null;
export function getOgBackground() { export function getOgBackground() {
if (cachedBackground) return cachedBackground;
try { try {
const bgPath = join(process.cwd(), 'public/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-100.jpg'); const bgPath = join(process.cwd(), 'public/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-100.jpg');
const bgBase64 = readFileSync(bgPath, 'base64'); const bgBase64 = readFileSync(bgPath, 'base64');
return `data:image/jpeg;base64,${bgBase64}`; cachedBackground = `data:image/jpeg;base64,${bgBase64}`;
return cachedBackground;
} catch (err) { } catch (err) {
console.error('[OG] Failed to load background', err); console.error('[OG] Failed to load background', err);
return undefined; return undefined;
} }
} }
let cachedLogo: string | null = null;
export function getOgLogo() { export function getOgLogo() {
if (cachedLogo) return cachedLogo;
try { try {
const logoPath = join(process.cwd(), 'public/assets/logo-white.png'); const logoPath = join(process.cwd(), 'public/assets/logo-white.png');
const logoBase64 = readFileSync(logoPath, 'base64'); const logoBase64 = readFileSync(logoPath, 'base64');
return `data:image/png;base64,${logoBase64}`; cachedLogo = `data:image/png;base64,${logoBase64}`;
return cachedLogo;
} catch (err) { } catch (err) {
console.error('[OG] Failed to load logo', err); console.error('[OG] Failed to load logo', err);
return undefined; return undefined;

View File

@@ -139,7 +139,7 @@
"prepare": "husky", "prepare": "husky",
"preinstall": "npx only-allow pnpm" "preinstall": "npx only-allow pnpm"
}, },
"version": "2.2.93", "version": "2.2.94",
"pnpm": { "pnpm": {
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [
"@parcel/watcher", "@parcel/watcher",