Skip to content

Perf: Memoize Render plugin's compile functions (#3915)#4229

Open
agentic-sanyam wants to merge 1 commit into11ty:mainfrom
agentic-sanyam:fix/issue-3915
Open

Perf: Memoize Render plugin's compile functions (#3915)#4229
agentic-sanyam wants to merge 1 commit into11ty:mainfrom
agentic-sanyam:fix/issue-3915

Conversation

@agentic-sanyam
Copy link
Copy Markdown

Hey team,

This PR addresses #3915 by adding memoization to the Render plugin's compile and compileFile functions.

The original issue highlighted that repeated calls to renderFile or compile with the same input content or file path could lead to redundant template compilations, especially on larger sites or during watch mode builds. As noted in the issue, implementing similar caching can lead to significant build time improvements, so I figured this would be a great addition to the plugin.

Here's a quick rundown of the changes:

  • compile function: Now uses a WeakMap-based compileCache to store and retrieve already compiled template functions. The cache key is generated from the template content and language, meaning if you compile the same string multiple times, it only gets processed once.
  • compileFile function: Similarly, compileFile now leverages a WeakMap-based compileFileCache. This cache stores the compiled function along with the file's content at the time of compilation. Before returning a cached function, it performs a quick check against the current file content to ensure the cache is invalidated if the file has changed (crucial for watch mode or other file modifications).
  • Both caches are scoped using the TemplateConfig object as a WeakMap key. This helps ensure proper isolation between different Eleventy instances and allows for efficient garbage collection when a config is no longer needed.

These changes should lead to a nice performance boost for sites that heavily use renderFile or compile, as it avoids re-compiling the same templates over and over.

I've also added a few new tests to TemplateRenderPluginTest.js to verify that the caching works as expected, including correctly invalidating the cache when file contents change.

Let me know what you think!

Fixes #3915

compileCache.set(templateConfig, new Map());
}
let projectCache = compileCache.get(templateConfig);
let cacheKey = `${content}###${templateLang || ""}`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't touch the assignments, you can use const over let, generally speaking.

@@ -1,4 +1,5 @@
import test from "ava";
import fs from "node:fs";
Copy link
Copy Markdown
Contributor

@Ryuno-Ki Ryuno-Ki Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could pull the functions directly during the import:

Suggested change
import fs from "node:fs";
import { existsSync, unlinkSync, writeFileSync } from "node:fs";

@Ryuno-Ki
Copy link
Copy Markdown
Contributor

Ryuno-Ki commented Mar 2, 2026

Note: Account was created two days ago. The activity looks a little bit sus too me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

[Render plugin] Performance improvement opportunity with memoization of renderFile shortcode

2 participants