JavaScript Agent

The JavaScript diagnoses Browser environments. It is a script that can be automatically injected into web pages (of mime type text/html) via Java or Web Server Agents – or manually, by using the <script> tag in the page header, at design time if not otherwise possible.

Agent injection

To instrument a website, two script tags have to be injected: an inline tag and a tag with a src-attribute. The inline tag has to be injected as the very first script and consists of essential instrumentation parts of the JavaScript Agent. For best capturing experience it is recommended that also the second tag is injected right after the inline part, but before any other JavaScript.

Asynchronous injection

For AppMon 6.5 and later, the JavaScript Agent injects asynchronously by default using the defer script tag attribute (see MDN Documentation for details).

Asynchronously loaded scripts do not block page loads, but there are a few drawbacks. Since the Agent cannot redefine any library variables if they already have been initialized (like jQuery or AngularJS), it is strictly recommended that defer is also used for any third party frameworks to be instrumented. The JavaScript Agent must be available before those frameworks start initializing, otherwise it is not possible to capture actions triggered by scripts. You can always disable asynchronous injection by clearing the Load the JavaScript Agent asynchronously check box in <System Profile> > User Experience > Web applications.

Automatic injection

The following is a sample tag-combination automatically injected by the Agent as first of script tags in <head> at delivery of the web page – with settings according to the configuration in <System Profile> > User Experience: <script type="text/javascript">(function(){var a=window;a.dT_?a.console&&a.console.log("Duplicate agent injection detected, turning off redundant initConfig."):window.dT_||(window.dT_={cfg:"tp=0,50,10|lab=1|reportUrl=dynaTraceMonitor|agentUri= /ajax/dtagent_pqtx_0000000.js|auto=1|domain=#DOMAIN#|rid=RID_1640928385| rpid=1646377341|app=#APP#"})})();...</script><script type="text/javascript" src="/dtagent_bdpx_0000000.js"></script>

The first tag (without src-attribute) is the agent’s initialization code. It must be delivered inline and is executed synchronously. It performs early-wrapping of native browser functions and third party libraries if available to ensure capturing can be done reliably.

The second tag requests the part of the JavaScript Agent that can be loaded asynchronously and therefore won’t block a page from being loaded. The filename defines it’s version and which parts of the Agent should be delivered:

  • dtagent is the JavaScript Agent Name set in <System Profile> > User Experience > Global Settings.
  • 7000000001289 is the AppMon Agent version (major, minor, revision, buildnumber).
    Each part of the version string consists of four characters, trimming leading zeroes, such that it is read like this: 7 0000 0000 1289, which translates to 7.0.0.1289.
  • bdpx is the feature hash, and shows information captured by the Agent, such as bandwidth, dojo, perceived render time and basic XHR detection.

Disabling JavaScript Agent Injection for a Specific Files / Locations

You can disable JavaScript Agent injection for specific files and/or locations.

To disable injection:

  1. Right click your system profile and select Edit System Profile -> your agent group -> Sensor Configuration item -> User Experience, and click Properties.
  2. In the URI-specific injection behavior area, click +.
  3. Specify the file or location to be excluded from the injection, in the Condition and URI pattern fields. See User Experience sensor properties for parameters description.
  4. From the Injection Rule list, select do not inject on this agent, to allow agents from other groups to inject here or do not inject on this and subsequent agents, to completely disable agent injection.

Manual injection

If the preferable auto-injection is not possible you need to insert the initialization tag manually at design time as first script tag in <head>. Since the initialization tag and it’s contained code varies depending on your application settings, it can easily be retrieved by using the Server REST Interfaces API using https://<AppMon server>:8021/api/v1/profiles/<systemprofile>/applications/<application>/javascriptagent/initcode

The initialization code performs operations to load the JavaScript Agent (either with or without the defer attribute) and updates it’s configuration if required. It is not necessary to update the initialization tag every time you change the UEM configuration, though adjustments are applied faster for new visitors if you do so.

Analysis performed by the JavaScript Agent

  • Detection of page loads.
  • Detection of user actions: A user action can be a page load or an Ajax call that the user initiates by a mouse click, key press, etc. Cascading calls are correlated into one single user action, for example a page load that performs several Ajax calls during load.
  • Browser errors.
  • The client’s bandwidth.
  • User action details such as action duration and page load detail timings for each action step, including browser timings, visually complete, and speed index.

The JavaScript Agent analyzes the above browser and user behaviors on the client side and captures actions if the corresponding event handler is registered.
It sends this information to the instrumented web server using several parameters in the monitor signal / simple XHR / Ajax request. The web server is named dynaTraceMonitor by default – resulting in a path relative to the instrumented server. Set the items in <System Profile> > User Experience. Set the monitor request name in the Global Settings tab. Set the monitor request path in the <applicationName>.

By default the signal is sent immediately after a page was successfully loaded or an Ajax action is finished. If a user navigates to another page before the page finished loading, the signal is sent during a beforeunload or unload event.

Action name detection

The JavaScript Agent tries to find a meaningful name for an action. To do this, it checks several properties (such as inner HTML, caption, or hint) of the HTML element (such as button or anchor) that triggers the action. It also tries to get the caption if there is a more complex HTML structure with multiple nested tags.

Set Action Name with Custom Attribute data-dtname

If the standard action name detection does not suffice you can set the custom attribute data-dtname within the HTML tags and use it as a caption. For example:

<label for="txtFirstname">Firstname</label> <input data-dtname="Firstname Text Input" type="text" value="firstname" name="firstname" title="Firstname" id="txtFirstname" />

The above leads to the following caption:

click on "Firstname Text Input"

Resolving captions for actions

As mentioned above, there are several mechanisms how the JavaScript Agent decides which name fits an action best.
It starts with the innermost HTML node that’s clicked (such as a button, image tag, link…) and checks the following things in order of precedence):

  1. The attribute named data-dtname.
  2. The nodeName (such as image, anchor, input, …), returns if html, body or head tag or the document element is found.
  3. The innerText / textContent.

If none of these return any reasonable result, the Agent starts a recursive algorithm that checks different things depending on the nodeName of the currently checked HTML node. If nothing is found, the parent node is checked.

Bandwidth detection

To detect a client’s bandwidth, the JavaScript Agent requests signals of different sizes from the server. These GET-requests force the Agent to generate images of a specific file size and send them back to the browser. The bandwidth is calculated according to the loadtime of these images. To reduce failures and guarantee the validity of the results, we recommend that you allow GET-requests on dynaTraceMonitor?bwstate=*. Do not gzip or compress the requests. This reduces the file size of the generated images and the time it takes the clients to download them and such biases bandwidth to be better than it actually is.

Which features is it needed for?

  • Bandwidth measure
  • Network contribution time measure, calculated based on bandwidth and on resource size which is measured on the server side
  • User experience index for page actions for bandwidths lower than broadband
    The threshold is multiplied by a factor between 1 and 2. Max. factor is 2.

How is it implemented?

  • Bandwidth detection triggers 2 seconds after the JavaScript Agent was loaded
  • The JavaScript Agent loads a series of fixed size images (0k, 3k, 10k, 30k, 100k, 300k, 1000k) and measure the time
  • First (0k) image is used for latency calculation, which are subtracted from all other measurements
  • All subsequent images are loaded until the download time without latency exceeds 100ms

What can be configured?

  • Bandwidth detection can be enabled per application (default: off)
  • Can be enabled separately for mobile browsers (default: off)
  • Frequency of bandwidth checks can be configured (default: every 5min)

What is the impact? The bandwidth detection can have an impact on the user experience, because it might be triggered while the page is still loading. Even if there is no impact on the response time, synthetic tools still might consider the timings of the bandwidth check images for their calculation of the response time.

  • Typical impact on the response time: 0 - 100ms (depending on individual page performance)
  • Impact on the total resource size of a page: up to 1443k

The bandwidth feature requires an instrumented agent to get the generated images, thus it just measures the bandwidth between the client and the Java/Webserver Agent. If the latter is located elsewhere, for example in a UEM only scenario with CORS, the measured bandwidth does not reflect the connection speed between the webserver that delivered the actual page and the browser.