Skip to content

Commit 38e73b7

Browse files
Merge pull request #40 from dportillo-ixs/copilot/fix-slow-initial-render
Optimize build performance: disable dev minification, add content-hash caching, increase debounce
2 parents a871743 + 5ad3682 commit 38e73b7

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

packages/htmldocs/src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const setupHotreloading = async (
4949

5050
changes = [];
5151

52-
}, 150);
52+
}, 500);
5353

5454
const absolutePathToDocumentsDirectory = path.resolve(
5555
process.cwd(),

packages/htmldocs/src/utils/get-document-component.tsx

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as es from "esbuild";
22
import fs from "node:fs";
3+
import crypto from "node:crypto";
34
import { BuildFailure, type OutputFile } from "esbuild";
45

56
import {
@@ -16,6 +17,15 @@ import postCssPlugin from "esbuild-style-plugin";
1617
import { RawSourceMap } from "source-map-js";
1718
import logger from "~/lib/logger";
1819

20+
// Build cache to avoid rebuilding unchanged files
21+
const MAX_CACHE_SIZE = 50;
22+
const buildCache = new Map<string, {
23+
documentComponent: any;
24+
documentCss: string | undefined;
25+
renderAsync: typeof renderAsync;
26+
sourceMapToOriginalFile: RawSourceMap;
27+
}>();
28+
1929
export const getDocumentComponent = async (
2030
documentPath: string
2131
): Promise<
@@ -30,6 +40,25 @@ export const getDocumentComponent = async (
3040
logger.debug(`[getDocumentComponent] Starting build for: ${documentPath}`);
3141
const startTime = performance.now();
3242

43+
// Check cache based on file content hash
44+
let fileContent: string | undefined;
45+
let hash: string | undefined;
46+
try {
47+
fileContent = await fs.promises.readFile(documentPath, 'utf-8');
48+
hash = crypto.createHash('md5').update(fileContent).digest('hex');
49+
50+
if (buildCache.has(hash)) {
51+
logger.debug(`[getDocumentComponent] Using cached build for ${documentPath}`);
52+
const cachedResult = buildCache.get(hash)!;
53+
const totalTime = performance.now() - startTime;
54+
logger.debug(`[getDocumentComponent] Cache hit in ${totalTime.toFixed(2)}ms`);
55+
return cachedResult;
56+
}
57+
} catch (cacheError) {
58+
// If cache check fails, continue with normal build
59+
logger.debug(`[getDocumentComponent] Cache check failed, proceeding with build`);
60+
}
61+
3362
let outputFiles: OutputFile[];
3463
try {
3564
logger.debug('Starting esbuild');
@@ -38,7 +67,7 @@ export const getDocumentComponent = async (
3867
entryPoints: [documentPath],
3968
platform: "node",
4069
bundle: true,
41-
minify: true,
70+
minify: false,
4271
write: false,
4372
format: "cjs",
4473
jsx: "automatic",
@@ -127,12 +156,28 @@ export const getDocumentComponent = async (
127156
const totalTime = performance.now() - startTime;
128157
logger.debug(`[getDocumentComponent] Total processing completed in ${totalTime.toFixed(2)}ms`);
129158

130-
return {
159+
const result = {
131160
documentComponent: executionResult.DocumentComponent,
132161
documentCss,
133162
renderAsync: executionResult.renderAsync,
134163
sourceMapToOriginalFile: sourceMapToDocument,
135164
};
165+
166+
// Cache the successful result using the hash computed earlier
167+
if (hash) {
168+
buildCache.set(hash, result);
169+
170+
// Limit cache size to prevent memory leaks
171+
if (buildCache.size > MAX_CACHE_SIZE) {
172+
const firstKey = buildCache.keys().next().value;
173+
if (firstKey) {
174+
buildCache.delete(firstKey);
175+
}
176+
}
177+
logger.debug(`[getDocumentComponent] Result cached with hash ${hash}`);
178+
}
179+
180+
return result;
136181
} catch (error) {
137182
logger.error('[getDocumentComponent] Processing error:', error);
138183
return {

0 commit comments

Comments
 (0)