Summary

JavaScript Function Monitor 2.1 is a script-based debugging tool. It is very useful for identifying performance problems from within the browser. Works in Internet Explorer and Netscape Navigater 4.x and above, and in Mozilla-based browsers.

Function Monitor integrates with JavaScript Profiler for ease of metric collection.

Index

Modification History

AuthorDateDescription
Stephen W. Cote04/29/2008Version 2.1. Updated to support object-prefixed function names. Enhanced the tracing capability.
Stephen W. Cote11/02/2005Version 2.0.

Introduction

License

It's Liberal, and the same as engine.license.txt.

Foreward

The function monitor (fondly known as funmon) is a JavaScript-based tool that acts as a dispatch for function calls, and tracks the amount of time it takes to run a particular function. Scripted functions are an often-overlooked source of performance problems, and these functions can be difficult to monitor. FunMon is a method of monitoring JavaScriptby using JavaScript.

[ top ]

How It Works

When a function is registered, it is replaced with a custom pointer that in turn is redirected to FunctionMonitor.dispatch. Each time a registered function is invoked, the function actually calls the new custom dispatch, which passes the unique function store name to the built-in dispatch. The built-in dispatch monitors its own processing time, as well as the amount of time it takes to invoke the registered function. The dispatch passes along the parameters to the original function, and dutifully passes back any return value. Metrics are recorded in an internal store for a given function.

When a function is unregistered, all metrics and custom dispatches are cleaned up.

Note: Funmon can be used to monitor itself. However, it adds additional performance overhead.

[ top ]

Download and Installation Instructions

  1. API Documentation.
  2. Download the FunMon2.js JavaScript file.
  3. Copy FunMon2.js to a location accessible by the page to be monitored.
  4. Add <SCRIPT SRC="[path]FunMon2.js"></SCRIPT> to the web page.
  5. Use the FunctionMonitor.register function to monitor one or more functions accessible by that page.
  6. You can use the optional frame and class parameters to monitor functions in other frames, and monitor functions defined on psuedo classes (via prototyping).

Browser Notes

Internet Explorer, Mozilla Ok.

Netscape Navigator 4.x Set the canTrace property to false, and remove the try{...}catch(e){...} block for Nav 4.

[ top ]

Reporting

Metric data is stored for each registered function, per call, up to the maximum stack length. Afterwards, the stack is overwritten when the value is greater than the current stack value. The FunctionMonitor.getAllMetrics function generates a text report of the collected metrics.

Report Structure

Applies to the report generated by FunctionMonitor.getAllMetrics. The actual metric data is stored in the functions array.

Each function is stored using a dispatch- prefix, followed by any frame reference, followed by any psuedo class name, and ending with the actual function name.

For example, a top level function named myTest would be reported as dispatch-myTest. A monitored function named myTest on a psuedo class object named CTest would show up as dispatch-CTest--myTest. Finally, a monitored function named myTest on a psuedo class object named CTest in a frame named theFrame would be reported as dispatch-theFrame-CTest--myTest. Note that frame names are suffixed with a single hyphen, and class names are suffixed with a double hyphen.

The metrics for each function are displayed beneath each function name. The structure of the metric is: #n time: t where n is the occurence in the stack, and t is the number of milliseconds it took for the function to run. Following each time, the optional metrics process (aka offset) and trace (if canTrace is true) may appear. process is the amount of time, in milliseconds, that FunctionMonitor.dispatch took outside of monitoring the function. The process metric is only printed if it is greater than 0. The trace metric shows the function stack trace, or the route through which the function was called. Note that the dispatch removes itself from the trace.

Example Report

The following data was taken from the funmon_dom.html sample included in the distribution archive. These results were obtained from Mozilla 0.9.3 on Win32. Mozilla on Linux takes about twice as long to run these tests.

dispatch-_runExample:
 #0 time=1442
 #1 time=1473
 #2 time=1442

dispatch-CTest--doTest:
 #0 time=0
 #1 time=0
 #2 time=0

dispatch-someTest:
 #0 time=10
 #1 time=20
 #2 time=10

dispatch-bigTest:
 #0 time=1422
 #1 time=1443
 #2 time=1432

dispatch-traceTest:
 #0 time=0
 #1 time=0
 #2 time=0

dispatch-oFunFrame-funFrameTest:
 #0 time=0
 #1 time=0
 #2 time=0

dispatch-oFunFrame-CFrame--frameTest:
 #0 time=0
  process:10
 #1 time=0
 #2 time=0

[ top ]

API

Refer to the Function Monitor API document for additional examples, and member documentation.

[ top ]

Known Issues/Bugs

  • Setting the canTrace property to true for Nav 4.x will cause it to stall.
  • Function tracing adds about a 25% overhead to the time it takes to run a function. This value is erroneously added (for some unknown reason) to the function time, and not the process offset.
  • It is not known if unregistering a function completely cleans up all internal references. Repeatedly registering/unregistering a function will cause successive register/unregister calls to take longer.
  • Don't use funmon to monitor itself unless specifically testing its own time. You can do it, if you register the register and unregister functions, you will double the time it takes to run a function because the dispatch gets looped back into itself. The metrics are still valid, it just takes that much longer to call register and unregister.

[ top ]

Release Notes

v2.1:

  • Add support for object prefix in function name when registering and unregistering functions.
  • Add helper method to check whether a function is registered.
  • Add better stacktrace support, including parameter values (some values annotated).

v2.0:

  • Refactored into global FunctionMonitor object.
  • Changed code structure to use similar style as Engine classes.

v1.5:

  • Function redirections in dispatch now use the apply method; this saves a lot of space and precious milliseconds.
  • _gunid was removed; it is not used with the use of apply.

v1.4:

  • Functions can now be unregistered.
  • Prototyped functions can now be monitored.

[ top ]

Examples

Example 1

function test(){
   for(var i=0;i<10000;i++){
      var d=new Date();
      var t=d.getTime();
      var e=parseFloat(t);
   }
}
FunctionMonitor.register("test");
// test is now monitored.
test();
alert(FunctionMonitor.getAllMetrics());
FunctionMonitor.unregister("test");
// test is not monitored.
	

Example 2

function CTest(){
   this.cname="test 1";
}
CTest.prototype.doTest(){
   // body for doTest
}
var ct=new CTest();
FunctionMonitor.register("doTest",null,"CTest");
// CTest.prototype.doTest is now monitored, inherited for all instances.
ct.doTest();
FunctionMonitor.unregister("doTest",null,"CTest");
// CTest.prototype.doTest is not monitored.
	

[ top ]