Improve JavaScript Performance Analysis Results with User Marks

Share this article

This article is part of a web dev tech series from Microsoft. Thank you for supporting the partners who make SitePoint possible.

When working on advanced JavaScript code, like a 3D engine, you may ask yourself what you can do to optimize performance, and how much time you should spend working on specific pieces of code. In this tutorial, I’ll share several tools that provide insight into how your code is performing, and show you how to make the most of user marks in the memory graph to analyze your performance.

Can’t wait to see what this article is about? Watch this video.

Feel free to ping me on Twitter if you want to discuss this article!

Need a Profiler?

One that comes to mind is the integrated profiler you can find using the new updates to the Internet Explorer F12 Dev Tools, enhancements that will also be available for Project Spartan. Of course, you can use any similar tools you prefer on your dev box. If you want to try this out on Android, iOS, or Mac OS, you can also use remote.IE to get an instance of Windows 10 Technical preview running in minutes. Then open the Internet Explorer “e” you’ve been avoiding (it is a temporary client shell that has Project Spartan’s new rendering engine configured), hit “F12” and now you can see what I’ll show you:

IE F12 tools

Please note that with the new F12 tools that we shipped with Windows 10 Technical preview, profiler is now part of the UI responsiveness window:

The Profiler

Let’s see other options that can give you more insights into how your code is performing.

console.time

You just have to call console.time() and console.timeEnd() around the piece of code you want to evaluate. The result is a string in your console displaying the time elapsed between time and timeEnd.

This is pretty basic and can be easily emulated but I found this function really straightforward to use.

Even more interesting, you can specify a string to get a label for your measurement.

This is for instance what I did for Babylon.js:

console.time("Active meshes evaluation");
this._evaluateActiveMeshes();
console.timeEnd("Active meshes evaluation");

This kind of code can be found around all major features and then, when performance logging is enabled, you can get really great info:

Spartan’s console

Be warned that rendering text into the console can consume CPU power

Even though this function is not standard, browser compatibility is pretty great, with Chrome, Firefox, IE, Opera and Safari all supporting it.

Performance Object

If you want something more visual, you can use the performance object as well. Among other interesting features to help you measure a web page’s performance, you can find a function called mark that can emit an user mark.

A user mark is the association of a name with a time value. You can measure portions of code with this API in order to get precise values. You can find a great article about this API by Aurelio de Rosa on SitePoint.

The idea today is to use this API to visualize specific user marks on the UI Responsiveness screen:

UI responsiveness screen empty

This tool allows you to capture a session and analyze how the CPU is used:

UI responsiveness screen loaded

We can then zoom in on a specific frame by selecting an entry called Animation frame callback and right-clicking on it to select filter to event.

The selected frame will then be filtered then:

The filter to event screen

Thanks to the new F12 tools, you can then switch to JavaScript call stacks to get more details about what happened during this event:

The JavaScript callstack

The main problem here is that it is not easy to understand how code is dispatched during the event.

This is where user marks enter the game. We can add our own markers and then be able to decompose a frame and see which feature is the most expensive and so on.

performance.mark("Begin something…just now!");

Furthermore, when you create your own framework, it is super handy to be able to instrument your code with measurements:

performance.mark("Active meshes evaluation-Begin");
this._evaluateActiveMeshes();
performance.mark("Active meshes evaluation-End");
performance.measure("Active meshes evaluation", "Active meshes evaluation-Begin", "Active meshes evaluation-End");

Let’s see what you can get with babylon.js for instance with the “V8” scene:

A V8 engine rendered in babylon.js

You can ask babylon.js to emit user marks and measures for you by using the debug layer:

The V8 engine scene with a debug layer overlayed

Then, using the UI responsiveness analyzer, you can get this screen:

The UI responsiveness analyzer

You can see that user marks are display on top of the event itself (the orange triangles) as well as segments for every measure:

The pageload timeline

This is then super easy to determine that, for instance, Render targets and Main render phases are the most expensive.

The complete code used by babylon.js to allow users to measure performance of various features is the following:

Tools._StartUserMark = function (counterName, condition) {
  if (typeof condition === "undefined") { condition = true; }
  if (!condition || !Tools._performance.mark) {
    return;
  }
  Tools._performance.mark(counterName + "-Begin");
};

Tools._EndUserMark = function (counterName, condition) {
  if (typeof condition === "undefined") { condition = true; }
  if (!condition || !Tools._performance.mark) {
    return;
  }
  Tools._performance.mark(counterName + "-End");
  Tools._performance.measure(counterName, counterName + "-Begin", counterName + "-End");
};

Tools._StartPerformanceConsole = function (counterName, condition) {
  if (typeof condition === "undefined") { condition = true; }
  if (!condition) {
    return;
  }

  Tools._StartUserMark(counterName, condition);

  if (console.time) {
    console.time(counterName);
  }
};

Tools._EndPerformanceConsole = function (counterName, condition) {
  if (typeof condition === "undefined") { condition = true; }
  if (!condition) {
    return;
  }

  Tools._EndUserMark(counterName, condition);

  if (console.time) {
    console.timeEnd(counterName);
  }
};

Thanks to F12 tools and user marks you can now get a great dashboard about how different pieces of your code are working together.

More Hands-on with JavaScript Articles

It might surprise you, but Microsoft has a bunch of free lessons on many open source JavaScript topics and we’re on a mission to create a lot more with Project Spartan coming. Check out my own:

Or our team’s learning series:

And some free tools: Visual Studio Community, Azure Trial, and cross-browser testing tools for Mac, Linux, or Windows.

This article is part of the web dev tech series from Microsoft. We’re excited to share Project Spartan and its new rendering engine with you. Get free virtual machines or test remotely on your Mac, iOS, Android, or Windows device at modern.IE.

David CatuheDavid Catuhe
View Author

David Catuhe is a Principal Program Manager at Microsoft focusing on web development. He is author of the babylon.js framework for building 3D games with HTML5 and WebGL. Read his blog on MSDN or follow him on Twitter.

Babylon.jsMDCperformanceperformance-tutorials
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week