critical
critical copied to clipboard
Multiple HTML sources
Hey guys, is it possible to specify multiple HTML sources? Usecase: I've got the homepage and one more important entry point, a landing page. Now I need the critical CSS of both combined and inlined and all the rest in a separate file. Is there any way to do that? I read Issue #38, but I never got working what was described there. Thanks & merry christmas ;)
Multiple HTML sources are not supported by now. You may generate the critical css for both pages and squash the styles together with clean-css
.
But why don't you just inline the critical css for the homepage in the head of your homepage and the one for the landingpage in the landingpage?
The method suggested by @bezoerb is best, to generate critical CSS for each file.
This is how I did it (using Gulp):
// Critical Render path CSS tasks - https://github.com/addyosmani/critical-path-css-demo#tutorial
gulp.task('copystyles', function() { // Copy our site styles to a site.css file for async loading later
return gulp.src(['dist/styles/main.css'])
.pipe($.rename({
basename: 'site'
}))
.pipe(gulp.dest('dist/styles'));
});
// Generate & Inline Critical-path CSS
gulp.task('critical', function(cb) {
runSequence(['default'], ['criticalhome', 'criticalblog'], cb);
});
gulp.task('criticalhome', ['copystyles'], function(cb) {
// At this point, we have our
// production styles in main/styles.css
// As we're going to overwrite this with
// our critical-path CSS let's create a copy
// of our site-wide styles so we can async
// load them in later. We do this with
// 'copystyles' above
critical.generate({
// Inline the generated critical-path CSS
// - true generates HTML
// - false generates CSS
inline: true,
base: 'dist/',
// HTML source file
// src: ['index.html','blog/index.html','typography/index.html'],
// src: 'index.html',
src: 'index.html',
// styleTarget: 'styles/main.css',
// Your CSS Files (optional)
css: ['dist/styles/main.css'],
// htmlTarget: 'index.html',
// Viewport width
width: 1300,
// Viewport height
height: 900,
// Target for final HTML output.
// use some css file when the inline option is not set
dest: 'dist/index.html',
// Minify critical-path CSS when inlining
minify: true,
// Extract inlined styles from referenced stylesheets
extract: true,
// ignore css rules
ignore: ['font-face']
}, cb);
});
gulp.task('criticalblog', ['copystyles'], function(cb) {
critical.generate({
inline: true,
base: 'dist/',
src: 'blog/index.html',
css: ['styles/main.css'],
width: 1300,
height: 900,
dest: 'dist/blog/index.html',
minify: true,
extract: true,
ignore: ['font-face']
}, cb);
});
Multiple HTML sources will be very useful for AngularJS with multiple views, where all critical css of every view (at least home and landing pages) should be inline in the index.html
This would also be extremely useful for CMS builds, which arguably could use these kinds of speed improvements the most. I'm trying to get this working with WordPress, and there really doesn't appear to be an elegant way to do it. I can't really generate a new CSS file for every page, because there may be new pages created, or the site may be too large to make that feasible (having hundreds of custom header.php files for a gigantic site wouldn't really work).
What I'd really like to be able to do is specify an array of "key" pages that get parsed, and a single combined critical gets output. Yes, there would be some unused code depending on the page being viewed, but this is a lot more practical than going the other route.
Until this is supported (and I know it may never be), my plan is to loop through a set of pages, generating CSS, and then cleaning it up any duplicate code and injecting it in to my header. It'll be kind of a mess, but it should work.
You're right, @JacobDB. Loop through the HTML files, concatenate the generated critical CSS files, then use a plugin like nano
to remove duplicate code and minify the output.
To reduce the strain of unneeded critical CSS on per page basis, I use loadCSS to sift through the code and apply critical styles as needed.
@stephenasamoah I ended up creating an array of one example page per template, using that to generate a critical CSS file for each template, and including it on each page that uses the same template. Seems to be working alright for me, but I'll definitely look in to your suggestions :)
+1 enhancement for managing multiple HTML sources.
+1 for this request. I've found my own solution as explained here but doing multiple html source files at once would eliminate having to initialise lots of chromium instances and a separate call to clean-css
to combine the outputs into one.
There's a problem when generating the critical css for multiple resources. If the paths differ we will end up with different asset paths for the same resources. Imagine the following scenario:
CSS /styles/main.css
...
.used-everywhere {
background-image: url('../images/test.jpg');
}
...
File 1: /index.html -> background-image: url('images/test.jpg');
File 2: /info/imprint.html -> background-image: url('../images/test.jpg');
So depending on which file got processed first, one of these two sites would definitely have a broken image.
@bezoerb use rebase property , this will solve the image path. https://www.npmjs.com/package/critical
For anyone who wants to loop trough all the html files and update the critical internal css. Use this: https://github.com/TheVoxSiren/voxsiren.net/blob/main/.github/workflows/optimizecss.yml#L32
it’ll loop trough all the html files and it uses a clever sed command to remove the online internal css, so that critical can add a up to date one (no duplicates)