-
-
Notifications
You must be signed in to change notification settings - Fork 496
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
Can Eleventy cache filters or template includes? (memoize) #840
Comments
One place that does cache output evaluation is in processing templates. So we can add the I already have a meta folder for content that needs to be processed. 2019.vtcodecamp
├── _includes/ # runtime includes
│ ├── scripts/ # script includes
│ │ ├── polyfill.js
│ │ ├── nav-toggle.js
│ │ └── site.js
├── _layout/ # layout templates
│ └── default.njk
├── posts/ # content posts
├── pages/ # core pages
├── meta/ # site meta content
│ ├── search.11ty.js # /search.json
│ ├── rss-feed.njk # /feed.xml
│ └── script-bundle.njk # /scripts.js
└── .eleventy.js # config information for 11ty Option A) - Add to IncludesIf we use File: ---
eleventyExcludeFromCollections: true
permalink: "_includes/scripts/bundle.js"
permalinkBypassOutputDir: true
---
{% set js %}
{% include "_includes/scripts/polyfill.js" %}
{% include "_includes/scripts/nav-toggle.js" %}
{% include "_includes/scripts/site.js" %}
{% endset %}
{{ js | jsmin | safe }} It's important for both git and the eleventy watch process that you not commit this file since it's technically a build artifact - so update your .gitignore as well File: _includes/scripts/bundle.js Then the default layout can consume the bundle we just built as if it were regular includes File: <script type="text/javascript">{% include "_includes/scripts/bundle.js" %}</script> CAUTION: This works almost perfectly, however seems to fail on the first build where the Option B) - Add to CollectionsIf we didn't prevent it being added to collections as in option a, we could read the Here's what our script bundler would look like: File: ---
permalink: "/scripts/bundle.js"
---
{% set js %}
{% include "_includes/scripts/polyfill.js" %}
{% include "_includes/scripts/nav-toggle.js" %}
{% include "_includes/scripts/site.js" %}
{% endset %}
{{ js | jsmin | safe }} That can be injected into any template via File: eleventyConfig.addCollection("bundles", col => {
let scriptCol = col.getFilteredByGlob("**/meta/script-bundle.njk")
return {
script: scriptCol[0]
}
}); And then access the collection from the layout template like this: File: <script type="text/javascript">
{{ collections.bundles.script.templateContent | safe }}
</script> And here's our new and improved metrics for a 75% reduction in build times and 90% reduction in filter load: |
3.0.0-alpha.15 will ship with a memoization layer around the Note that benchmarking output will still reflect the unmemoized call count (e.g. 998× below):
Note that you can memoize a filter or shortcode in your Eleventy configuration file (in any version) right now. Here’s an example using the import memoize from "memoize";
export default function(eleventyConfig) {
eleventyConfig.addLiquidFilter("htmlEntities", memoize(str => {
return encode(str);
}));
}; I think this usage is probably the right level of abstraction for most use cases, rather than complicating the configuration API with extra stuff. |
I'm using both the Quick Tips here:
So my default layout looks roughly like this:
Which works to embed any sitewide CSS & JS inline on every single page
Every page will be the same (and if I do need page-specific styles, I can handle them separately) - so it would be preferable for build times to only do the JS and CSS minification once, since the input should be identical and the minification should be a pure function
Currently, the build times scale linearly with the number of pages being built and the filters take up about 10 seconds out of a 12.5s build:
And a simple log on the filter function confirms that the same process is executed on every single page build.
Perhaps I can memoize the minifiy function, but since it's processing about 20k characters, the content hash is gonna be huge.
Another idea was to pull out the scripts into a separate template:
File:
/_includes/partials/scripts.njk
And then include it in my layout page:
File:
/layouts/default.njk
But that would be under the hopes that there's a way to cache a template include?
The text was updated successfully, but these errors were encountered: