If you have an inline profiling system, with some slight modifications, you can view that data in the Chrome web browser rather than writing a visualization tool yourself.

Having a nice graphical representation of profiling data is crucial to finding critical hotspots in a realtime application. Creating a viewer application for that custom data is a massive time sink, so before you start writing ones, know your options.

Getting started with profiling your game

Ahh performance —  that three syllable word that accounts for the headache-causing and most often avoided part of the game development cycle. Once in a development blue moon your manager will ramble into your office in a deep sweat, shouting about performance and expect you to do something about it.

search the Internet to find ways to uncover the hotspots in your code. You’ll also learn some important information to consider when deciding what kind of profiling to use in order to discover where your code is spending its time.

current program counter against a known set of debugging symbol data.

Each type of profiling has its pros and cons. External profiling does a great job at keeping your existing codebase clean, but suffers from a lack of resolution and overwhelming data density. Most external profilers will generate sample data by polling the target application at regular intervals (usually capped at 1ms), so the granularity of your sampling is limited by that constraint. If you make a call to 30 separate functions during that millisecond sampling interval, that information won’t be displayed in the resulting data (rather you may see a single function taking 1ms of time). In addition, external profilers are non-discriminatory, meaning they sample your data and give information for whatever functions are being called, on whatever threads, regardless of what you’re looking for. The excess data can make it difficult to navigate the profiling timeline to see what’s really going on.

There are several benefits and drawbacks to consider when using inline profiling.  Inline profiling offers you the opportunity to choose the resolution you need because you can use high frequency timers right in your code.  It also provides additional flexibility and granularity since you can get insert timings at a per-function and per scope level.  However, it does so with the sacrifice of littering your codebase with functions to evaluate timings. This code change is so invasive that many developers have to create separate builds and testing configurations during production to properly exclude the profiling functions at runtime.  

data. They often expend man-years of effort sunk into drawing boxes on a screen and adding proper UI information to navigate massive datasets.

Using chrome://tracing to peek under the hood

pretty awesome web browser.

chrome://tracing. What’s great about this tool is that it allows you to capture profiling data about what Chrome is doing under the hood, so you can properly adjust your javascript execution, or optimize your asset loading. Chrome://tracing offers an intimate view of the browser’s performance, recording all of Chrome’s activities across every thread, tab, and process.

Do you know what’s going on under the hood of your web browser? chrome://tracing does.

console.timeEnd(“eventname”) events, allowing you to directly profile your custom Javascript code alongside the rest of what Chrome is executing.

Viewing external profile data files


The chrome://tracing tab acts as a visualizer for inline profiling data. You can scan, scrub, select, and more with this tool, allowing you to analyze your game profile data directly.

Understanding the chrome://tracing JSON data

non-optimized JSON file containing a sequence of event blocks. Each block includes the following name/value pairs:

  • ‘cat’ – the category for this event. Useful when doing larger grouping (eg “UnitUpdates”)
  • ‘name’ – the name of this event (eg ‘PathingUpdate’)
  • ‘pid’ – the processor ID that spawned this event
  • ‘tid’ – the thread ID that spawned this event
  • ‘ts’ – the processor time stamp at the time this event was created
  • ‘ph’ – the phase or type of this event
  • ‘args’ – any programmatic metadata that’s attached to this event

For an example, a JSON file with a single begin/end sample is listed below. Note that an event include descriptions of its category as well as its name. Some events occur in pairs, which are marked by complementary phases (B/E or S/F – read more about that below).



"cat": "MY_SUBSYSTEM",  //catagory

"pid": 4260,  //process ID

"tid": 4776, //thread ID

"ts": 2168627922668, //time-stamp of this event

"ph": "B", // Begin sample

"name": "doSomethingCostly", //name of this event

"args": { //arguments associated with this event.




Some sample data from the profiler’s format. You can see there’s a named category, as well as a name of the scoped event we’re tracking. Some  events come in pairs of phases (see below).


Understanding the phase (‘ph’) tag

Sample Begin/End events ( ph = B / E )

The most common event types are sample begin and sample end, denoted by setting the phase tag to “B” and “E” respectively. These events define the start and end points of a sampling time interval.

Instant events ( ph = I )

Instant events, denoted with an “I” phase tag, are great for tossing extra information into the stream to mark actions or events in your game, such as LevelLoadComplete, or  SuperHugeMonsterStartedAttack.

Instant markers in the timeline appear as small triangles. The visual difference is crucial when scrubbing over large portions of data.


Async Start/Finish events ( ph = S/F )

Async events can occur across multiple threads/processes. They are useful for tracing operations like texture loads that can start activity on other threads. The start of an async event is denoted by setting the phase tag to “S” (for start) and the end by setting the tag to “F” (for finish).

Event metadata (args)

Along with instances, chrome://tracing supports per-sample metadata (called args in the format), which can be filled in with name/value pairs of arbitrary data. This appends information to a specific event. Anyone who’s scrubbed through inline profiling data will tell you that these types of markers are invaluable when you get barraged by a flood of samples with the same call stack and need a way to determine the data associated with each instance.

Every Event and Instance can have annotated data associated with it, which is very helpful in tracking down unique data relating to a sample.

Adding capture-specific metadata

Another nice feature of the JSON format for capture analysis is the ability to append specific capture-specific metadata to the trace that may be helpful in analysis of the bigger picture. For instance storing what developer did the capture, what OS they are running, hardware specs, etc.

As mentioned, chrome:tracing will gladly accept the following syntax:


   {       "cat": "MY_SUBSYSTEM", …..   },

   {     "cat": "MY_SUBSYSTEM",...       },


And in order to add meta data, you can modify the format thusly:


  traceEvents: [ /*the previous format data goes here*/ ],

  someData: “this is some capture specific data”,

  someMoreData: “generated by tPhips@blah.com”


When you utilize the 2nd form of the JSON format, upon file-load, a button in the UI will popup labeled ‘METADATA’ that shows all the non-trace event data in a stringified form.

Generating a chrome://tracing compliant JSON file

chrome://tracing and hitting the Record tab, running, then hitting the Stop tracing button. This action will record the inline profiling events generated by all the open tabs and processes running in Chrome. You can then save the data to disk and examine its format.


Moving chrome://tracing forward

The tracing page inside of Chrome offers a powerful timeline viewing tool, and like any tool, it is constantly being improved.  Here’s what you need to know about working with chrome://tracing in the future.

  1. Like most Google products, the Javascript front-end code for rendering the timeline is open sourced, which is highly valuable for those of you looking to embed the process in your own applications, build-bot, or compliance testing web pages.
  2. Make sure you can find and report bugs with the tracing tool inside of chrome.
  3. In Case the JSON format doesn’t suit your fancy, the chome://tracing authors accept contributions on what types of timeline file/data formats to support.
  4. The Systrace feature recently added to the Android SDK lets developers use the same profiling UI to analyze the performance of their native applications.

Looking for more information? Check out the how to use chrome://tracing guide and get started using this powerful tool to display profiling data from your game.