Open mtsknn opened 3 years ago
One of the issues with the suggested change above is that the caching is based on the inputPath
, not the str
. Any changes to a file will use the previously cached version. Using the template string as the key should get the desired results.
It's actually possible to replicate this change in your 11ty project configuration by overriding the Pug library with a wrapper to cache the templates.
// .eleventy.js
const pug = require("pug")
const pugCache = {}
module.exports = function (config) {
config.setLibrary("pug", {
compile: (str, options) => {
if (pugCache[str]) return pugCache[str]
pugCache[str] = pug.compile(str, options)
return pugCache[str]
},
})
}
It's also worth noting that this doesn't handle dependencies in any way. Any changes to files that are included in your templates will be ignored on subsequent builds.
Caching wouldn’t be an issue if the cache was cleared at the end of each build though, right?
Caching wouldn’t be an issue if the cache was cleared at the end of each build though, right?
No it wouldn't be an issue. Dependencies will only cause a problem if you persist the cache, which would happen in the code snippet I've added above.
Is there hook in 11ty to run a function before or after a build runs, so the cache could be reset?
Actually looks like 11ty's events is what I'm looking for.
Updated snippet that clears the cache after a build has run.
// .eleventy.js
const pug = require("pug")
module.exports = function (config) {
let pugCache = {}
// Reset the cache
config.on("eleventy.after", () => {
pugCache = {}
});
config.setLibrary("pug", {
compile: (str, options) => {
if (pugCache[str]) return pugCache[str]
pugCache[str] = pug.compile(str, options)
return pugCache[str]
},
})
}
Still, it would be much nicer if this was handled by the built-in Pug compiler, and handled caching across builds while managing dependencies.
(Psst! This Issue should be tagged with template-language:pug)
Is your feature request related to a problem? Please describe.
Build times of Eleventy sites using Pug templates can quickly get out of hand because:
Describe the solution you'd like
Cache Pug templates to speed up builds. Two example implementations are presented below.
Other template types might benefit from caching as well (I haven't tested), so I'm not sure if a Pug-specific caching solution is ideal.
Pug has a
cache
option (see Pug's API reference), but it "only applies torender
functions." Eleventy uses thecompile
function, so thecache
option is not an option (pun intended).Describe alternatives you've considered
Moving away from Pug templates. 😄 I'm going to do it soon anyway (Preact ftw 💪) so implementing Pug template caching is not critical for me, but I think Pug (or at least Pug layouts) is a poor choice for Eleventy projects until caching is implemented.
Additional context
Here's how I reduced build times from ~6 seconds to ~2.5 seconds and subsequent builds from ~4.5 seconds to less than a second.
Build times from my Eleventy site (+ content files from a separate, private repo):
Let's see where some of the time is spent by adding console loggings to
node_modules/@11ty/eleventy/src/Engines/Pug.js
:What's happening?
Let's add simple caching to
Pug.js
:this.cache = {};
to the constructor.Result:
Now Pug templates are compiled only once per build, making builds much faster.
We can make builds even faster by implementing a cache that persists between builds:
const cache = {};
toPug.js
, before the class declaration.Result:
Now Pug templates are cached between builds, making subsequent builds take less than a second. Nice. 😎
Not sure how robust my implementation is, but it's clear that caching would be extremely nice.
Didn't find similar issues. 11ty/eleventy#108 and 11ty/eleventy#984 might be somewhat related, but they are still different.