Web performance is gaining interest in IT world since 2010. There are many tools that can help you in making and keeping your site fast. Google’s PageSpeed, YSlow and WebPagetest to name just a few of them. But what if you want to run these tools regularly (as a part of Continuous Integration) or get in-depth web performance metrics?

phantomas is a command line tool build on top of PhantomJS – scriptable headless browser running on WebKit. phantomas gives you not only an overview with metrics such as number of requests, domains used, resources timing, but also in-depth view of what’s happening inside CSS and JS code of your site – number of events bound, DOM & jQuery selectors, DOM node insertions, number of complex CSS selectors, calls to window.eval and window.write etc. It also gives you the possibility to report metrics from JS code of the page phantomas is run against.

phantomas is build as a set of simple modules that bind to events emitted by the core. Metrics can be reported in plain (aka verbose) format, but also as JSON, CSV or TAP. I’ll show how to use the later one for WebPerf Continuous Integration.

The command line

phantomas requires PhantomJS 1.9 and nodejs (for analyzing CSS). Let’s install it by running the following (it will install the latest version of PhantomJS as well):

npm install --global phantomas

and check how well “Performance Calendar” website behaves:

phantomas --url http://calendar.perfplanet.com/2012/ --verbose

WebPerf Continuous Integration

Improving your site’s performance is just one side of the webperf coin. Keeping it fast is even more challenging. phantomas can help you with that by providing TAP formatted output that can be easily consumed by CI tools like Jenkins.


TAP format comes from Perl unit tests. phantomas can act as a webperf “unit tests” runner that checks whether values of given metrics stay below given set of values (aka asserts).

Let’s head to the example:

{"url": "http://phantomjs.org", "verbose": true, "log": "log/phantomjs.log", "block-domain": "google-analytics.com", "cookies": [{"name": "mobile", "value": "on", "domain": ".phantomjs.org"}], "asserts": {"requests": 12, "redirects": 0, "domains": 2, "timeToFirstByte": 600, "httpTrafficCompleted": 1000}}

JSON pasted above can be passed as a config file to phantomas via --config option. asserts entry contains a set of values that these metrics should meet (aka should be less or equal). Metrics that failed this check are reported in TAP (and other output formats as well) and phantomas finishes with exit code that is equal to number of failed asserts.

For instance:

$ phantomas --config config.json --format tap (...) not ok 1 requests --- expected: 12 actual: 15 ... (...) $ $? 1

Generated TAP file can then be consumed by Continuos Integration tool (like Jenkins) or even a simple TAP parsing tool (tap-eater).


Let’s say that we want to start with a simple automated webperf CI / monitoring. We’d like to get an email when something becomes worse than expected.

First, let’s install tap-eater that will consume TAP file and send emails with reports:

npm install --global tap-eater

The following bash script should do the magic:

#!/usr/bin/env bash TS=`date +%Y%m%d-%H:%M:%S` TAP=$TS.tap phantomas --config config.json --format tap --log phantomas.log > $TAP cat $TAP | tap-eater -v --email-to "webperf.guy@site.net" --email-subject "phantomas - site.net monitoring"

This script can be run periodically via cron and it will send a message on email address provided whenever at least one metric does not meet given asserts.

What’s next?

There are plans to extend phantomas with SPOF checker and various integrations (sending metrics to StatsD and JUnit output format).

phantomas is hosted on GitHub. Please contribute by adding new ideas and submitting pull requests.

Let’s make the web even faster in 2014!


Maciej Brencz is a Software Engineer at Wikia. He specializes in Web Performance and building scalable websites, struggling to send as less bytes as possible.

He spends a part of his free time on GitHub or enjoying another juicy bit of kæstur hákarl.