mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 06:30:03 +00:00
perf(producer): cache local font compression (#2397)
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { existsSync, readFileSync } from "node:fs";
|
import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
||||||
|
import { tmpdir } from "node:os";
|
||||||
|
import { join } from "node:path";
|
||||||
import { compressToWoff2, fontToDataUri } from "./fontCompression.js";
|
import { compressToWoff2, fontToDataUri } from "./fontCompression.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,6 +43,26 @@ describe("compressToWoff2", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("fontToDataUri", () => {
|
describe("fontToDataUri", () => {
|
||||||
|
it("reuses cached compression across calls", async () => {
|
||||||
|
const cacheDir = mkdtempSync(join(tmpdir(), "hf-local-font-cache-"));
|
||||||
|
const raw = Buffer.from("stable-font-content");
|
||||||
|
let compressionCalls = 0;
|
||||||
|
const compressImpl = async () => {
|
||||||
|
compressionCalls += 1;
|
||||||
|
return Buffer.from("compressed-font-content");
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const first = await fontToDataUri(raw, "ttf", { cacheDir, compressImpl });
|
||||||
|
const second = await fontToDataUri(raw, "ttf", { cacheDir, compressImpl });
|
||||||
|
|
||||||
|
expect(second).toBe(first);
|
||||||
|
expect(compressionCalls).toBe(1);
|
||||||
|
} finally {
|
||||||
|
rmSync(cacheDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it("skips compression for woff2 input and returns a data URI", async () => {
|
it("skips compression for woff2 input and returns a data URI", async () => {
|
||||||
const raw = Buffer.from("fake-woff2-bytes");
|
const raw = Buffer.from("fake-woff2-bytes");
|
||||||
const uri = await fontToDataUri(raw, "woff2");
|
const uri = await fontToDataUri(raw, "woff2");
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
// @ts-expect-error -- wawoff2 ships no type declarations; ambient .d.ts only visible to producer's own tsconfig
|
// @ts-expect-error -- wawoff2 ships no type declarations; ambient .d.ts only visible to producer's own tsconfig
|
||||||
import wawoff2 from "wawoff2";
|
import wawoff2 from "wawoff2";
|
||||||
|
import { createHash } from "node:crypto";
|
||||||
|
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
||||||
|
import { homedir, tmpdir } from "node:os";
|
||||||
|
import { dirname, join } from "node:path";
|
||||||
|
|
||||||
const { compress } = wawoff2 as {
|
const { compress } = wawoff2 as {
|
||||||
compress: (input: Buffer | Uint8Array) => Promise<Uint8Array>;
|
compress: (input: Buffer | Uint8Array) => Promise<Uint8Array>;
|
||||||
@@ -18,12 +22,77 @@ function rawMimeType(format: string): string {
|
|||||||
return RAW_MIME_TYPES[format] ?? "font/ttf";
|
return RAW_MIME_TYPES[format] ?? "font/ttf";
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fontToDataUri(input: Buffer, originalFormat: string): Promise<string> {
|
type FontCompressionOptions = {
|
||||||
|
cacheDir?: string;
|
||||||
|
compressImpl?: (input: Buffer) => Promise<Buffer>;
|
||||||
|
};
|
||||||
|
|
||||||
|
function defaultCacheDir(): string {
|
||||||
|
const root =
|
||||||
|
process.env.HYPERFRAMES_FONT_CACHE_DIR ??
|
||||||
|
(process.env.AWS_LAMBDA_FUNCTION_NAME
|
||||||
|
? join(tmpdir(), "hyperframes", "fonts")
|
||||||
|
: join(homedir(), ".cache", "hyperframes", "fonts"));
|
||||||
|
return join(root, "local-compression-v1");
|
||||||
|
}
|
||||||
|
|
||||||
|
function cachedCompressionPath(input: Buffer, originalFormat: string, cacheDir: string): string {
|
||||||
|
const digest = createHash("sha256")
|
||||||
|
.update("hyperframes-local-font-compression-v1\0")
|
||||||
|
.update(originalFormat)
|
||||||
|
.update("\0")
|
||||||
|
.update(input)
|
||||||
|
.digest("hex");
|
||||||
|
return join(cacheDir, `${digest}.woff2`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readCachedCompression(path: string): Buffer | null {
|
||||||
|
try {
|
||||||
|
if (!existsSync(path)) return null;
|
||||||
|
const cached = readFileSync(path);
|
||||||
|
return cached.length > 0 ? cached : null;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cacheCompression(path: string, compressed: Buffer): void {
|
||||||
|
const tmpPath = `${path}.tmp-${process.pid}-${Date.now()}`;
|
||||||
|
try {
|
||||||
|
mkdirSync(dirname(path), { recursive: true });
|
||||||
|
writeFileSync(tmpPath, compressed, { flag: "wx", mode: 0o644 });
|
||||||
|
renameSync(tmpPath, path);
|
||||||
|
} catch {
|
||||||
|
// A concurrent process may have populated the cache, or the cache may be
|
||||||
|
// read-only. Compression still succeeded, so rendering can continue.
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
rmSync(tmpPath, { force: true });
|
||||||
|
} catch {
|
||||||
|
// Best-effort cleanup only.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fontToDataUri(
|
||||||
|
input: Buffer,
|
||||||
|
originalFormat: string,
|
||||||
|
options: FontCompressionOptions = {},
|
||||||
|
): Promise<string> {
|
||||||
if (originalFormat === "woff2") {
|
if (originalFormat === "woff2") {
|
||||||
return `data:font/woff2;base64,${input.toString("base64")}`;
|
return `data:font/woff2;base64,${input.toString("base64")}`;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const compressed = await compressToWoff2(input);
|
const cachePath = cachedCompressionPath(
|
||||||
|
input,
|
||||||
|
originalFormat,
|
||||||
|
options.cacheDir ?? defaultCacheDir(),
|
||||||
|
);
|
||||||
|
const cached = readCachedCompression(cachePath);
|
||||||
|
if (cached) return `data:font/woff2;base64,${cached.toString("base64")}`;
|
||||||
|
|
||||||
|
const compressed = await (options.compressImpl ?? compressToWoff2)(input);
|
||||||
|
cacheCompression(cachePath, compressed);
|
||||||
return `data:font/woff2;base64,${compressed.toString("base64")}`;
|
return `data:font/woff2;base64,${compressed.toString("base64")}`;
|
||||||
} catch {
|
} catch {
|
||||||
console.warn(
|
console.warn(
|
||||||
|
|||||||
Reference in New Issue
Block a user