Categories
Links of Interest

Article Roundup for 04.03.2015

Categories
Scripts

Using criticalCSS with Gulp.js

I have a site that is using Gulp.js as its task runner. I wanted to use criticalCSS on the site and because there isn’t a Gulp plugin quite yet, I had to roll it myself.

I’m going to try and tackle writing the plugin myself, but for the time being, here is a quick script to get it running:

gulp.task('critical', function() {
  var request = require('request');
  var path = require( 'path' );
  var criticalcss = require("criticalcss");
  var fs = require('fs');
  var tmpDir = require('os').tmpdir();

  var cssUrl = 'http://localsite.dev/wp-content/themes/theme_name/style.css';
  var cssPath = path.join( tmpDir, 'style.css' );
  var includePath = path.join( __dirname, 'inc/critical.css.php' );
  request(cssUrl).pipe(fs.createWriteStream(cssPath)).on('close', function() {
    criticalcss.getRules(cssPath, function(err, output) {
      if (err) {
        throw new Error(err);
      } else {
        criticalcss.findCritical("http://localsite.dev/", { rules: JSON.parse(output) }, function(err, output) {
          if (err) {
            throw new Error(err);
          } else {

            fs.writeFile(includePath, output, function(err) {
              if(err) {
                return console.log(err);
              }
              console.log("Critical written to include!");
            });

          }
        });
      }
    });
  });

});

As you’ll probably notice, this is a WordPress site, but you can tweak some of the parameters in here to meet your needs. I have the inlined css outputting into an include called critical.css.php. You can reference my post on Using criticalCSS in WordPress on how to output this include in your <head>.

Categories
Links of Interest

Link: Know These Web Dev Building Blocks

I often think about the technologies I’ve learned over the past 8 years as a Front-End Developer and wonder what it must be like for someone coming into this field. I think the best answer is to take it one tool at a time.

This article is a great comprehensive list of what should be learned as a web developer.

Know These Web Dev Building Blocks

One part I had a little issue with was the section on Development Frameworks (i.e. Bootstrap). He isn’t wrong in saying that you should know how to use these, but I would add a caveat that these frameworks aren’t the silver bullet for every project. Just because you need, say a grid system, doesn’t mean you have to start with all of Bootstrap.

Overall, a great read!

Categories
Scripts

Using criticalCSS in WordPress

I’ve been obsessed with optimizing websites for awhile, and one big hurdle to a faster website is “render-blocking” JavaScript and CSS. This came up as I was trying to get a high score on Google PageSpeed Insights.

Screenshot of Render Blocking Error in PageSpeed Insights | "83/100 Speed. Consider Fixing: Eliminate render-blocking JavaScript and CSS in above-the-fold content"

Google recommends you move these scripts and css files to the bottom of the DOM (just before the </body>). With CSS, it’s a little more complicated because you have to figure out the “above the fold” (ugh hate that term) styles and inline them in the <head>. More on that in the criticalCSS section.

Assumed knowledge of enqueuing

This post assumes knowledge of enqueuing scripts/styles in WordPress. If you haven’t used these functions in WordPress, I’d highly recommend brushing up on them. Regardless of if you want to use criticalCSS or not, this is a much better way to insert styles/scripts into a theme. Here are some good resources:

Moving JavaScript to bottom of the DOM

Luckily, WordPress has built-in mechanisms to put your script at the bottom of the DOM. The 5th parameter of the wp_enqueue_script() function is a boolean $in_footer. which tells WordPress whether or not to put it in the footer. Here’s a quick example inside your functions.php:

wp_enqueue_script( 'mysite_main', get_template_directory_uri() . '/js/main.min.js', array('jquery'), '4.0', true );

“jQuery is still in the <head>”

By default, jQuery is enqueued in the <head>. We can change this pretty easily in functions.php:

wp_deregister_script('jquery');
wp_register_script('jquery', "//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js", false, null, true);
wp_enqueue_script('jquery');

In this example, I also chose for the Google CDN version of jQuery. Notice again the last param set to true, just like our enqueues above.

“jQuery is STILL in the <head>!”

Now you should see jQuery at the bottom of the DOM, right? Maybe not actually.

If you have a plugin that is dependent on jQuery and puts their script in the <head>, WordPress will keep jQuery in the head (as it should, otherwise, you’d get a “$ is not defined” error). You have a few options:

  1. Edit that plugin to make sure that nothing breaks if you set $in_footer to true in all of the enqueues. Assuming it works, contact the plugin author so they can change it.
  2. Use a plugin that moves all scripts to the footer (hit or miss).
  3. Deregister then reregister the plugin’s scripts. This is a little more risky because if the plugin changes the name of their script, you could get some broken JavaScript.

I’m partial to option 1, as it nips the problem in the bud, assuming the plugin author is responsive on the support forum. 🙂

At this point, you may run into a brick wall. Sometimes plugins do crazy things and it’s almost impossible to get the script/style where you want it. Luckily, the more well-known plugins (i.e. Contact Form 7) do these things correctly.

Get CSS to bottom of DOM

Getting CSS in the footer in WordPress is a little more tricky. The wp_enqueue_style() function doesn’t support $in_footer (maybe they’ll add it someday), so we’ll have to get our hands dirty. Instead of using the wp_enqueue_style() function, we are going to manually echo the <link> tag in the functions.php (I know, I know. Just after I lectured you on how great enqueuing is):

function styles_in_wp_foot() {
	echo '<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Ubuntu:400,700,400italic,700italic|Bitter" type="text/css" media="all" />';
	echo '<link rel="stylesheet" href="' . get_stylesheet_uri() .'" type="text/css" media="all" />';
}

add_action( 'wp_footer', 'styles_in_wp_foot' );

If you reload your site, you’ll see a flash of unstyled html until the css is loaded. We don’t want this. Enter criticalCSS.

criticalCSS

Now, we have to generate the inlined styles for the <head>. You can use a task runner like Grunt of Gulp to do this. Below is a Grunt configuration block. Please see the grunt-criticalcss docs for full implementation.

criticalcss: {
  custom: {
    options: {
      url: "http://localurl.vvv",
      // arbitrary width and height for critical to use when looking at "above the fold" styles.
      width: 1000,
      height: 800,
      outputfile: "inc/critical.css.php",
      filename: "style.css",
      buffer: 800*1024
    }
  }
},
Alternative to a task runner

Update: For those out there that are using a pre-built theme and don’t have a task runner, it might be easier to manually run a critcalCSS generator. Take the resulting css the tool gives you and dump it into the inc/critical.css.php file. Every time you update your css, you’ll want to run this tool again.

Now that we have that CSS in a file, we just need to echo the php include into the <head>. Add this to functions.php:

function criticalCSS_wp_head() {
	echo '<style>';
	include get_stylesheet_directory() . '/inc/critical.css.php';
	echo '</style>';
}

add_action( 'wp_head', 'criticalCSS_wp_head' );

Wrapping up

Screenshot of PageSpeed score of 96/100 for SuperiorCampers.comAs you see, the more scripts, styles and plugins you have installed, the more complex this can get. So keep those to a minimum, folks. 🙂

After this, you should see a huge uptick in your PageSpeed score if you are doing all the other (easier) things on the list. One of our clients’ sites has a 96/100.

Categories
Links of Interest

Article Roundup for 03.27.2015

More great links for this week. I’m off to WordCamp Atlanta 2015 today! If you happen to be going, let’s meet up! Hit me up on Twitter.