This relates to #6994 and #6993
[build]
useResoureceCacheOnly = false
createCSSClassMap = true
This needs some prototyping, but ref my comment in the other thread with purgecss either timing out or taking forever. I assume that most of this time is spent collecting class names.
So, if I instead could write something ala:
const purgecss = require('@fullhuman/postcss-purgecss')({
content: ['./public/.hugo-classmap.html'],
defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || []
})
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
...process.env.HUGO_ENVIRONMENT === 'production'
? [purgecss]
: []
]
}
I'm pretty sure that would be a considerable time saver.
Note to self: The class collecting would need to be done before #6994 ... so a concept of workgroup...
/cc @budparr @regisphilibert
OK, so I created a quick prototype of this one and, assuming I have done it correctly, the time savings are remarkable:
Before:
node_modules/postcss-cli/bin/postcss -o 845.09s user 45.41s system 113% cpu 13:06.55 total
node_modules/postcss-cli/bin/postcss -o 3.70s user 0.16s system 140% cpu 2.741 total
Note that the timing above is running PostCSS on the final output (in /public), but generating the "class map" file as part of the build in Hugo is neglible in this big picture.
/cc @regisphilibert @budparr
I have an even bigger site ... Before/after, both run with Hugo, the last variant uses the class map from the build:
Total in 1103193 ms
Total in 5277 ms
Quick question from people: What and where should I put this file? There may be others like it in the future ...
Right now I have just dumped it in public/hugo-cssclasses.txt -- as it is part of the build, but you probably don't want to publish it... Filename/folder? @regisphilibert @digitalcraftsman @onedrawingperday etc.
Damn, I need to think 馃 ! It's brilliant though!
I guess I wouldn't mind having it outside of the public dir so it's not published. If Hugo, in the future produces post build data to be stored in files, why not create a json (js friendly) file at the root already (hugo.json) to serve this purpose. cssclasses could be its lone key for now but build time could come next...
{
"cssclasses":"text-xl border-white...",
"build": {
"time": 1230
}
}
I wonder what @budparr thinks?
As long as it's easily parseable by purgecss (and it should), JSON sounds like a good idea. Not sure about the build time, some people would want to commit to source control, and I would hate (maybe) to have this file change on every build. Also, the main purpose for this file is to use it after the build, and you don't know the total build time until after you have processed it. Wrap your head around that.
hugo.json sounds a little too much like a config file, how about hugo_stats.json ...?
My local setup seems to work kind of nice with the following config. Note that it is possible to also run the below when in server mode (I have the purgecss on only for production in the example below).
/cc @regisphilibert @budparr
const purgecss = require('@fullhuman/postcss-purgecss')({
content: [ './hugo_stats.json' ],
defaultExtractor: (content) => JSON.parse(content).cssClasses.split(' ') || []
});
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
...(process.env.HUGO_ENVIRONMENT === 'production' ? [ purgecss ] : [])
]
};
While testing this, using classes only isn't coverage enough ... this needs element names and id attributes as well. Ref. https://github.com/FullHuman/purgecss-from-html/blob/master/index.js ... hmm... But luckily it doesn't know the context, only that the body element is there etc.
Most helpful comment
OK, so I created a quick prototype of this one and, assuming I have done it correctly, the time savings are remarkable:
Before:
Note that the timing above is running PostCSS on the final output (in /public), but generating the "class map" file as part of the build in Hugo is neglible in this big picture.
/cc @regisphilibert @budparr