Determining which styles are in your Critical Rendering Path

Going through the slides from Ilya Grigorik‘s Velocity presentation on Optimizing the Critical Rendering Path, I saw another opportunity for automation.  It would be very tedious to take an existing site (especially one with a lot of CSS) and determine which styles were used “above the fold” by hand.  But it should be easy to determine which elements are initially in the viewport, and which styles affect them, programmatically.

the theory

  • Determine the viewport. this can be changed as necessary to meet your particular needs
  • Determine which elements are NOT in the initial viewport…
  • …and remove them.
  • Check your CSS rules to see which ones are still used. These belong in your critical rendering path.

the method

  • Make a mirror of the page.
    mkdir orig && wget -E -H -k -K -p -nH --adjust-extension
  • and a copy to play with:
    cp -r orig modified
  • make them available via HTTP any way you like.
  • execute your script and make your CSS changes:
    phantomjs aboveTheFold.js --url=
  • then test to see if there’s a difference:
    phantomjs speedreport.js --url= > tmp/orig/report.html
    phantomjs speedreport.js --url= > tmp/modified/report.html

the result

After running through the tests a few times, this approach appears to shave around 100ms off the page load time even without altering the original CSS, only moving those requests to the bottom of the body.  The script has a few obvious shortcomings and as yet did not catch every rule that I would like, but it’s a good start.

Analyzing CSS Rules

Ever wonder just how many unused CSS Rules you have laying around?  You can enumerate your stylesheets and CSS Rules in the browser for stylesheets that originate from the same domain, but that doesn’t help you much if you serve your static CSS files from a CDN.  As it turns out, you can disable the security in PhantomJS using --web-security=false.  You can then enumerate all stylesheets regardless of their domain and test to see how many elements match each selector, if any. I added a quick example to my burgeoning toolkit to create a pie chart showing each stylesheet’s rules as matched (bluish) or unmatched (redish).  The chart below was created using phantomjs --web-security=false cssCheck.js --url=

matched and unmatched CSS selectors by stylesheet

matched and unmatched CSS selectors by stylesheet

Testing web UI interaction response times with CasperJS

I’ve written a few utilities lately to measure how fast a page loads over the wire.  While watching Nicholas Zakas’ presentation at Velocity, I started wondering how I would measure the load times for popups, tabs, and other dynamic content loaded via user interaction.  CasperJS has already proven extremely handy for automating some pretty complex functional tests that had previously been done manually, so I pulled that out of the tool box to see if I could add some measurements.

Unfortunately, Nicholas’ demo was so fast and consistent that the numbers didn’t look believable :-) So, like most web developers, I turned to jQuery. And, as always, jQuery had exactly what I needed. The jQuery UI Tabs Example came complete with dynamically loaded, slow, and even broken tabs.  The Gist and output are below.

var colorizer = require('colorizer').create('Colorizer');
var casper = require('casper').create();
var totalTests=3;
casper.start('', function(){
	casper.viewport(1024, 768);
	this.test.assertHttpStatus(200, "The page has loaded.");
	this.test.assertSelectorExists('#tabs', "We got tabs.");
	this.test.assertVisible('#tabs-1', "Content 1 is visible.");
testTabLoad('#ui-id-2', '#ui-tabs-1', "Tab 1", "tab1.png");
testTabLoad('#ui-id-3', '#ui-tabs-2', "Tab 2", "tab2.png");
testTabLoad('#ui-id-4', '#ui-tabs-3', "Tab 3 (slow)", "tab3.png");
testTabLoad('#ui-id-5', '#ui-tabs-4', "Tab 4 (broken)", "tab4.png"); {
function testTabLoad(tab, content, name, capfilename){
	casper.then(function() {
		if(name)casper.echo(name, "COMMENT");
		this.test.assertSelectorExists(tab, "Tab selector exists.");
		this.test.assertSelectorExists(content, "Content selector exists.");
		this.test.assertDoesntExist(content+'>p', "Content is not already populated.");
		this.test.assertNotVisible(content, "Content selector is not currently visible.");;
		this.waitUntilVisible(content+'>p', function(){
			casper.echo("Content became visible in " + ( + " ms", "INFO_BAR");
			if(capfilename)this.captureSelector(capfilename, content);


Raise your hands if you want to go faster.

Web development has reached escape velocity.  For me, personally, it has gone from a nuisance, to a hobby, to a job, to a passion.  There are entire industries built on and around the web now and the pace is accelerating.  There is a forest of information out there on how to build and optimize web apps, and it is tall and wide.  I’d like to share with you a few of the things I’ve learned along the way.

Thanks for stopping by,