diff --git a/packages/htmldocs/src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts b/packages/htmldocs/src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts
index 586aca5..134b5bd 100644
--- a/packages/htmldocs/src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts
+++ b/packages/htmldocs/src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts
@@ -49,7 +49,7 @@ export const setupHotreloading = async (
changes = [];
- }, 150);
+ }, 500);
const absolutePathToDocumentsDirectory = path.resolve(
process.cwd(),
diff --git a/packages/htmldocs/src/utils/get-document-component.tsx b/packages/htmldocs/src/utils/get-document-component.tsx
index 2ceb2f7..de72a42 100644
--- a/packages/htmldocs/src/utils/get-document-component.tsx
+++ b/packages/htmldocs/src/utils/get-document-component.tsx
@@ -1,5 +1,6 @@
import * as es from "esbuild";
import fs from "node:fs";
+import crypto from "node:crypto";
import { BuildFailure, type OutputFile } from "esbuild";
import {
@@ -16,6 +17,15 @@ import postCssPlugin from "esbuild-style-plugin";
import { RawSourceMap } from "source-map-js";
import logger from "~/lib/logger";
+// Build cache to avoid rebuilding unchanged files
+const MAX_CACHE_SIZE = 50;
+const buildCache = new Map();
+
export const getDocumentComponent = async (
documentPath: string
): Promise<
@@ -30,6 +40,25 @@ export const getDocumentComponent = async (
logger.debug(`[getDocumentComponent] Starting build for: ${documentPath}`);
const startTime = performance.now();
+ // Check cache based on file content hash
+ let fileContent: string | undefined;
+ let hash: string | undefined;
+ try {
+ fileContent = await fs.promises.readFile(documentPath, 'utf-8');
+ hash = crypto.createHash('md5').update(fileContent).digest('hex');
+
+ if (buildCache.has(hash)) {
+ logger.debug(`[getDocumentComponent] Using cached build for ${documentPath}`);
+ const cachedResult = buildCache.get(hash)!;
+ const totalTime = performance.now() - startTime;
+ logger.debug(`[getDocumentComponent] Cache hit in ${totalTime.toFixed(2)}ms`);
+ return cachedResult;
+ }
+ } catch (cacheError) {
+ // If cache check fails, continue with normal build
+ logger.debug(`[getDocumentComponent] Cache check failed, proceeding with build`);
+ }
+
let outputFiles: OutputFile[];
try {
logger.debug('Starting esbuild');
@@ -38,7 +67,7 @@ export const getDocumentComponent = async (
entryPoints: [documentPath],
platform: "node",
bundle: true,
- minify: true,
+ minify: false,
write: false,
format: "cjs",
jsx: "automatic",
@@ -127,12 +156,28 @@ export const getDocumentComponent = async (
const totalTime = performance.now() - startTime;
logger.debug(`[getDocumentComponent] Total processing completed in ${totalTime.toFixed(2)}ms`);
- return {
+ const result = {
documentComponent: executionResult.DocumentComponent,
documentCss,
renderAsync: executionResult.renderAsync,
sourceMapToOriginalFile: sourceMapToDocument,
};
+
+ // Cache the successful result using the hash computed earlier
+ if (hash) {
+ buildCache.set(hash, result);
+
+ // Limit cache size to prevent memory leaks
+ if (buildCache.size > MAX_CACHE_SIZE) {
+ const firstKey = buildCache.keys().next().value;
+ if (firstKey) {
+ buildCache.delete(firstKey);
+ }
+ }
+ logger.debug(`[getDocumentComponent] Result cached with hash ${hash}`);
+ }
+
+ return result;
} catch (error) {
logger.error('[getDocumentComponent] Processing error:', error);
return {