-
-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pug templates should be cached #4
Comments
One of the issues with the suggested change above is that the caching is based on the 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? |
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
:$ NODE_ENV=production npx @11ty/eleventy --quiet Compiling ./layouts/feeds.pug: 138.862ms Compiling ./layouts/home.pug: 90.025ms Compiling ./layouts/_layout.pug: 70.217ms Compiling ./layouts/sitemap.pug: 1.618ms Compiling ./layouts/blog.pug: 60.811ms Compiling ./layouts/blog-tag.pug: 50.042ms Compiling ./layouts/weekly-log.pug: 56.489ms Compiling ./layouts/blog-post.pug: 58.545ms Compiling ./layouts/blog-post.pug: 46.379ms Compiling ./layouts/blog-post.pug: 41.69ms Compiling ./layouts/blog-post.pug: 49.629ms Compiling ./layouts/blog-post.pug: 47.151ms Compiling ./layouts/blog-post.pug: 42.664ms Compiling ./layouts/blog-post.pug: 41.404ms Compiling ./layouts/blog-post.pug: 44.92ms Compiling ./layouts/blog-post.pug: 35.886ms Compiling ./layouts/blog-post.pug: 44.233ms Compiling ./layouts/blog-post.pug: 41.294ms Compiling ./layouts/blog-post.pug: 35.953ms Compiling ./layouts/blog-post.pug: 40.19ms Compiling ./layouts/blog-post.pug: 38.175ms Compiling ./layouts/blog-post.pug: 35.886ms Compiling ./layouts/blog-post.pug: 35.373ms Compiling ./layouts/blog-post.pug: 37.86ms Compiling ./layouts/blog-post.pug: 37.293ms Compiling ./layouts/blog-post.pug: 32.97ms Compiling ./layouts/blog-post.pug: 35.178ms Compiling ./layouts/blog-post.pug: 35.551ms Compiling ./layouts/blog-post.pug: 36.691ms Compiling ./layouts/blog-post.pug: 34.45ms Compiling ./layouts/blog-post.pug: 33.714ms Compiling ./layouts/blog-post.pug: 34.614ms Compiling ./layouts/blog-post.pug: 35.878ms Compiling ./layouts/blog-post.pug: 34.796ms Compiling ./layouts/blog-post.pug: 36.148ms Compiling ./layouts/blog-post.pug: 35.129ms Compiling ./layouts/blog-post.pug: 33.364ms Compiling ./layouts/blog-post.pug: 34.846ms Compiling ./layouts/blog-post.pug: 31.681ms Compiling ./layouts/blog-post.pug: 33.75ms Compiling ./layouts/blog-post.pug: 32.745ms Compiling ./layouts/blog-post.pug: 34.428ms Compiling ./layouts/blog-post.pug: 32.531ms Compiling ./layouts/blog-post.pug: 33.69ms Compiling ./layouts/blog-post.pug: 35.748ms Compiling ./layouts/blog-post.pug: 32.748ms Compiling ./layouts/blog-post.pug: 35.833ms Compiling ./layouts/blog-post.pug: 31.495ms Compiling ./layouts/blog-post.pug: 32.383ms Compiling ./layouts/blog-post.pug: 33.21ms Compiling ./layouts/blog-post.pug: 33.113ms Compiling ./layouts/blog-post.pug: 30.86ms Compiling ./layouts/blog-post.pug: 32.407ms Compiling ./layouts/blog-post.pug: 34.384ms Compiling ./layouts/blog-post.pug: 34.338ms Compiling ./layouts/blog-post.pug: 31.16ms Compiling ./layouts/blog-post.pug: 38.132ms Compiling ./layouts/blog-post.pug: 34.037ms Compiling ./layouts/blog-post.pug: 32.529ms Compiling ./layouts/blog-post.pug: 35.182ms Compiling ./layouts/blog-post.pug: 30.767ms Compiling ./layouts/blog-post.pug: 31.771ms Compiling ./layouts/blog-post.pug: 34.428ms Compiling ./layouts/blog-post.pug: 35.279ms Compiling ./layouts/blog-post.pug: 32.739ms Compiling ./layouts/blog-post.pug: 31.34ms Compiling ./layouts/blog-post.pug: 34.47ms Compiling ./layouts/blog-post.pug: 31.203ms Compiling ./layouts/blog-post.pug: 35.819ms Compiling ./layouts/blog-post.pug: 33.668ms Compiling ./layouts/blog-post.pug: 34.075ms Compiling ./layouts/blog-post.pug: 33.338ms Compiling ./layouts/blog-post.pug: 33.744ms Compiling ./layouts/blog-post.pug: 32.177ms Compiling ./layouts/blog-post.pug: 35.484ms Compiling ./layouts/blog-tags.pug: 35.683ms Compiling ./layouts/blog-post.pug: 34.884ms Compiling ./layouts/blog-post.pug: 36.529ms Compiling ./layouts/blog-post.pug: 33.07ms Compiling ./layouts/blog-post.pug: 35.898ms Compiling ./layouts/blog-post.pug: 33.485ms Compiling ./layouts/blog-post.pug: 35.539ms Compiling ./layouts/weekly-log-entry.pug: 36.904ms Compiling ./layouts/weekly-log-entry.pug: 40.974ms Compiling ./layouts/weekly-log-entry.pug: 32.911ms Compiling ./layouts/weekly-log-entry.pug: 35.647ms Compiling ./layouts/weekly-log-entry.pug: 33.011ms Compiling ./layouts/weekly-log-entry.pug: 40.249ms Compiling ./layouts/weekly-log-entry.pug: 32.898ms Compiling ./layouts/weekly-log-entry.pug: 33.9ms Compiling ./layouts/weekly-log-entry.pug: 31.833ms Compiling ./layouts/weekly-log-entry.pug: 33.963ms Compiling ./layouts/weekly-log-entry.pug: 34.613ms Compiling ./layouts/weekly-log-entry.pug: 33.033ms Compiling ./layouts/weekly-log-entry.pug: 35.005ms Compiling ./layouts/weekly-log-entry.pug: 34.522ms Compiling ./layouts/weekly-log-entry.pug: 34.465ms Compiling ./layouts/weekly-log-entry.pug: 33.936ms Compiling ./layouts/weekly-log-entry.pug: 33.482ms Compiling ./layouts/weekly-log-entry.pug: 31.985ms Compiling ./layouts/weekly-log-entry.pug: 36.188ms Compiling ./layouts/weekly-log-entry.pug: 36.18ms Compiling ./layouts/weekly-log-entry.pug: 32.65ms Compiling ./layouts/weekly-log-entry.pug: 38.105ms Compiling ./layouts/weekly-log-entry.pug: 33.64ms Compiling ./layouts/weekly-log-entry.pug: 34.06ms Compiling ./layouts/feed-rss.pug: 5.272ms Compiling ./layouts/weekly-log-entry.pug: 37.964ms Compiling ./layouts/weekly-log-entry.pug: 34.161ms Compiling ./layouts/weekly-log-entry.pug: 35.379ms Compiling ./layouts/feed-rss.pug: 4.525ms Compiling ./layouts/feed-rss.pug: 3.575ms Copied 24 files / Wrote 98 files in 5.85 seconds (59.7ms each, v0.12.1)
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.
The text was updated successfully, but these errors were encountered: