TYPO free


fighting for TYPO free code

An improved XHProf UI

An improved XHProf UI

There are several ways to find bottlenecks in PHP code. One of them is using a profiler. There are a couple of profilers to choose from; apd, xdebug, xhprof and zend_debugger. I like to use the XHProf profiler. There is an article by Steffen Gebert that explains how you set up the profiler module in PHP. If you don't have xhprof setup in PHP yet, come back here after you've read Steffen's article. I'll wait right here.

XHProf Browser extensions

The profiler can run in sample mode (e.g. profiling one request in a thousand) or it can be triggered by adding a URL parameter (&_profile=1) to the URL. I also use XDebug to debug code in combination with PHPStorm. XDebug can also be triggered by adding a URL parameter. There are several browser extensions available that make the triggering easier. You just click a toolbar- or locationbar button to enable or disable debugging.

I liked the ease with which the debugging can be started and stopped so much, that I created two XHProf helper extensions; one for Google Chrome and one for Firefox.

The extensions provide simple button you can click to enable or disable the profiling for a whole site. You can provide a list of domains for which to enable the button so it does not clutter the browser interface for non-development sites.

The good thing about using a cookie to enable or disable profiling, is that you can include the XHProf header for all your development sites, but only have it generate profiling data for sites that have the cookie set.


For storing and viewing the results, I use the modified version of the 'XHProf UI' by Paul Reinheimer. It allows for storing the results in a MySQL database and displays some of the metrics in pretty 'Highcharts powered' graphs.

I forked the preinheimer xhprof repository and made a few changes.

Zoomable SVG callgraph
Drill Down SVG zoomable callgraphs

XHProf UI can generate some very usefull call graphs. One thing I disliked was the speed of the callgraph generation. I fiddled with the settings a bit and discovered that 'png' dotfile generation was a lot quicker than the 'gif' dotfile generation. I later discovered that 'svg' files generated the fastest. Browsers can display svg natively these days, but navigation was a bit of an issue. The default scrolling and zooming is not so nice to work with. So I wrapped the svg in the jQuery panzoom plugin that enables easy panning and zooming of the svg.

I also dug into the graphviz documentation and found out that the svg allowed for attaching URL's to the nodes. This is great! It is now possible to 'drill down' inside a callgraph. By clicking a node, you will jump to the callgraph for that node.

Display only critical path by default

The call graph can still be quite large. When running extbase code; the number of distinct functions can grow to a couple of thousand. Even when setting a 'threshold', that filters out methods that take little time, graphviz can still take some time to render the callgraph.  Graphviz has to calculate a node layout that will render the shortest path and still show a nice hierarchy. But most of the time you will not be interested in the majority of the methods. You will probably be interested in the main bottlenecks in the code. These are highlighted in the callgraph as the 'critical path'. When displaying the callgraph, only the critical path is shown. You can also opt for the full callgraph if you wish, but starting with the critical path only is a great time saver.

Call spaghetti
Annotated labels and edges in callgraphs

The edges between the nodes now have a title attirbute set. This enables you to figure out where those 42 calls in the edge spaghetti are coming from and going to.

Easy domain filtering

On the run listings, a 'domain' column was added. Clicking on it will filter results to the clicked domain only.

Cleaned up URL comparison charts

The url comparison charts were cleaned up and the tooltips have been extended to also show the run-id and domain.

Most called methods
Extra detail charts for run detail

Two charts were added on the run detail view: 'most expensive calls by exclusive CPU time' and 'most called methods'. Clicking on the labels will show you the detail callgraph for that method.

Number formatting
Localised number formatting

And last but not least; since I live in Europe, I like to see a dot as a thousand separator and a comma as a decimal separator. The number formatting was cleaned up and now uses the configured locale and separators to render the numbers. The numbers are now shown in the appropriate units. So you will see 28,92 MB instead of 30320368. The 30320368 is still present as the table cell title attribute so you can inspect how much closely matching values actually differ.

Clone it from GitHub and enjoy.