critters
critters copied to clipboard
handling multiple HTMLWebpackPlugin instances & pruneSource
Critters doesn't appear to play nice with multiple HTMLWebpackPlugin instances when using pruneSource: true
(see snippet below).
Effectively, once Critters 'prunes' the original stylesheet then processes subsequent html pages, it can't extract css when it no longer exists in the source.
I'm not sure the best way we can fix this (or if it makes sense to?). For now I'm simply not pruning the source pruneSource: false
.
const URLS = [
{ "url": "/", "title": "Welcome" },
{ "url": "/tacos", "title": "Tacos" }
];
// ...
plugins: [
new CrittersPlugin({
mergeStylesheets: false,
logLevel: "error",
pruneSource: true // default
}),
...URLS.map(({ url, title }) => {
const options = {
string: true,
params: { url, title, mode }
};
const template = `!!prerender-loader?${JSON.stringify(options)}!${join(
src,
"index.html"
)}`;
return new HTMLWebpackPlugin({
template,
filename: join(dist, url, "index.html"),
favicon: join(src, "assets/favicon.ico"), // perf 101, avoid penalties with missing favicon
minify: isProd && {
// minify our html for a tidy response
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
removeScriptTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
},
inject: true // inject bundles assets automatically
});
}),
// ...
]
+1
In general, pruneSource
can't be used with multi-page sites, since it either over-prunes for some pages or produces one CSS file per-page. My recommendation has generally been to use pruneSource:false
when prerendering/generating multiple pages.
This might seem an odd choice, but the result is your lazy-loaded CSS is agnostic to the page and you don't end up with one cache entry per page (would be bad). I'm not 100% sure how other critical solutions handle this, but personally I've been having good luck with the non-pruning solution.