Automating Critical CSS with Gulp JS and WordPress

N.B. This tutorial is pretty outdated at this point and there are almost certainly better ways to do this, given most devs are moving to React-based SSRs where CSS in JS and styled components are reducing the need to consider stuff like this. However, I’m leaving it up because if you’re still using WordPress, it might help.

For this tutorial you will need:

1) A dev environment with Node and NPM (Node Package Manager) installed.
2) A front-end build.
3) A gulpfile in your root directory

Critical CSS is a fairly recent front-end development. However, the benefits are great and pretty obvious:

1) Site loads faster.
2) Because of that – users less likely to bounce from your site due to crappy initial load times.
3) It’s a neat thing that you can show all your friends and tell them what a great developer you are because your site loads instantly.

Boring Stuff Alert

Why Critical CSS is a good idea:

An initial TCP packet request is around 14kb, or in other words, your browser can download 14kb of data before it needs to make a round trip to the server. If you can load the CSS that’s most important (critical, see) to the site in that very short space of time, it makes the first load appear pretty instantaneous. That’s good.

For this reason, it’s suggested that you keep your Critical CSS to a maximum of 9-10KB, so you’ve got 4-5KB remaining for the HTML portion of the request.

The Nitty Gritty

In my case, I’m making a WordPress site, so I’m inside the theme folder. N.B. If you’re building with WordPress, you might want to consider using Sage by Roots, it’s pretty great and comes with an incredibly thorough gulpfile straight out of the box.

For this tutorial, I’m going on the assumption you’ve already got a gulpfile in place in your root/theme directory. If you don’t, take a look here for a guide on how to get started.


Open Terminal and navigate to your project directory — I do this with terminal because it’s just great.

cd path/to/your/project
npm install gulp-penthouse --save-dev

Well done, we’ve just navigated to our project directory and installed gulp-penthouse as a dev dependency in our package.json.

Now – let’s add gulp-penthouse to the top of our gulpfile.js.

var criticalCss = require('gulp-penthouse');

Next, we’ll add the critical-css task to our gulpfile.

gulp.task('critical-css', function () {
    return gulp.src('./dist/styles/main.css')
            out: 'critical.php', // output file name
            url: '', // url from where we want penthouse to extract critical styles
            width: 1400, // max window width for critical media queries
            height: 900, // max window height for critical media queries
            userAgent: 'Mozilla/5.0 (compatible; Googlebot/2.1; +' // pretend to be googlebot when grabbing critical page styles.
          safe:true // this isn't required, but I've included cssNano to minify the output file
        .pipe(gulp.dest('./templates/')); // destination folder for the output file

Even though penthouse is only extracting CSS here, we’re able to use whatever file extension we want for the output file, (N.B. I’ve used .php). Which means if we add the partial file to our header.php – shown below – WordPress will take care of updating the critical CSS partial whenever it’s refreshed.



We can automate the process even further by adding the critical-css task to your build process with gulp or gulp watch, like so:

/* WATCH */
gulp.task('watch', function() {[path.source + 'styles/**/*'], ['styles', 'critical-css']);

/* BUILD */
gulp.task('build', function(callback) {
              'critical-css', // run critical after your styles process has completed.
              ['fonts', 'images'],

/* DEFAULT - runs 'build' */
gulp.task('default', function() {

And that’s it! You have an automatically-updating Critical CSS partial using Gulp JS and WordPress.

Here’s a link to this gulpfile on GitHub. It’s essentially just Sage’s gulpfile with CombineMQ (great if you build OOCSS with embedded media queries or with BEM in mind) and penthouse for critical inlining.