diff --git a/eleventy.config.js b/eleventy.config.js
index d7a9a14..f2c19df 100644
--- a/eleventy.config.js
+++ b/eleventy.config.js
@@ -335,6 +335,22 @@ export default function (eleventyConfig) {
},
});
+ // Performance: skip PostHTML parsing for pages without
tags.
+ // Both registered PostHTML plugins (remote-image-marker, eleventy-img) only
+ // target
elements — no point parsing+serializing HTML without them.
+ // Overrides the default @11ty/eleventy/html-transformer transform (same name
+ // overwrites via addTransform) with a pre-check that avoids the full PostHTML
+ // parse/serialize cycle (~3ms/page) for image-free pages.
+ eleventyConfig.addTransform("@11ty/eleventy/html-transformer", async function(content) {
+ if (this.outputPath?.endsWith(".html") && !content.includes("
, , etc.)
+ // we must still run the full pipeline even without images.
+ const hasUrlCallbacks = eleventyConfig.htmlTransformer.getCallbacks("html", this).length > 0;
+ if (!hasUrlCallbacks) return content;
+ }
+ return eleventyConfig.htmlTransformer.transformContent(this.outputPath, content, this);
+ });
+
// Sitemap generation
eleventyConfig.addPlugin(sitemap, {
sitemap: {
@@ -874,17 +890,26 @@ export default function (eleventyConfig) {
});
// Filter AI-involved posts (ai-text-level > "0" or aiTextLevel > "0")
+ // Memoized: same collections.posts input produces same output — compute once per build
+ // (694 calls × 2,350 posts = 1.6M iterations without cache)
+ let _aiPostsCache = null;
+ let _aiStatsCache = null;
+ eleventyConfig.on("eleventy.before", () => { _aiPostsCache = null; _aiStatsCache = null; });
+
eleventyConfig.addFilter("aiPosts", (posts) => {
if (!Array.isArray(posts)) return [];
- return posts.filter((post) => {
+ if (_aiPostsCache) return _aiPostsCache;
+ _aiPostsCache = posts.filter((post) => {
const level = post.data?.aiTextLevel || post.data?.["ai-text-level"] || "0";
return level !== "0" && level !== 0;
});
+ return _aiPostsCache;
});
// AI stats — returns { total, aiCount, percentage, byLevel }
eleventyConfig.addFilter("aiStats", (posts) => {
if (!Array.isArray(posts)) return { total: 0, aiCount: 0, percentage: 0, byLevel: {} };
+ if (_aiStatsCache) return _aiStatsCache;
const total = posts.length;
const byLevel = { 0: 0, 1: 0, 2: 0, 3: 0 };
for (const post of posts) {
@@ -892,12 +917,13 @@ export default function (eleventyConfig) {
byLevel[level] = (byLevel[level] || 0) + 1;
}
const aiCount = total - byLevel[0];
- return {
+ _aiStatsCache = {
total,
aiCount,
percentage: total > 0 ? ((aiCount / total) * 100).toFixed(1) : "0",
byLevel,
};
+ return _aiStatsCache;
});
// Helper: exclude drafts from collections