Ottrelite Instrumentation for React provides two main ways to add performance tracing to your React applications:
useComponentRenderTracing"use trace" directiveIf you're using a recent version of React Native, consider using React Performance Tracks instead.
React Performance Tracks offer significantly more features compared to Ottrelite's basic render time tracking, including:
Ottrelite serves as an alternative solution for those who haven't upgraded to the latest React Native version yet.
First, ensure you are already using @ottrelite/core. Then, add this package:
The React API provides hooks that allow you to manually instrument your components. The main hook is useComponentRenderTracing, which traces a component's render lifecycle.
useComponentRenderTracingThis hook traces a component's render lifecycle (i.e., any - first or subsequent - render).
The hook must be called first in the component to mark the JS logic start time undelayed. Any components you render & return must first be stored in a variable, and returned after calling the hook's returned markJSRenderEnd function.
The traced span starts after the JS render logic finishes and ends after the component is rendered to the tree. Additionally, the JS render execution time is measured and reported as a jsLogicDuration attribute within the span.
The Babel plugin automatically instruments React components and hooks using the "use trace" directive. This provides a convenient way to add tracing without manually calling hooks.
Add the plugin to your Babel configuration. If you are using a babel.config.js file:
Add the "use trace" directive as the first line in functions you want to instrument:
render method bodyThe directive schema is "use trace [API] [Name]" where:
[API] (default: dev) - Either dev (Ottrelite Development API) or otel (OpenTelemetry JS SDK)[Name] (optional) - Custom name for the tracer; if not provided, the function/component name is used
As seen in the examples above, the components are wrapped in memo to prevent unnecessary re-renders. This is a common practice in React to optimize performance, but it is not compulsory - the instrumentation would still work without it. However, in such case, it would be expected that most likely the instrumentation would produce many entries, for invocations of the component which didn't actually result in an update to the shadow tree.
When using memo(), you must either:
memo(function MyComponent() { ... })"use trace dev MyComponent"Anonymous functions without explicit names will result in an error.
As seen in the example above, the component includes an explicit implementation of shouldComponentUpdate to prevent unnecessary re-renders. This is a common practice in React to optimize performance, but it is not compulsory - the instrumentation would still work without it. However, in such case, it would be expected that most likely the instrumentation would produce many entries, for invocations of the component which didn't actually result in an update to the shadow tree.
The tracer name is determined in the following priority order:
| Declaration style / context | Name |
|---|---|
Explicit name from the string after "use trace" | The passed string |
component with displayName or name | displayName or name property |
| named function/class | Name of the function/class |
| arrow function | Name of the assignment target identifier |
| anonymous function/class | Name of the assignment target identifier |
Both [API] and [Name] parameters are optional. The shortest form is "use trace" which is equivalent to "use trace dev <resolved component name>".
If you pass only one parameter, it will be treated as [API] first; if the value doesn't match the API options, it will be treated as the [Name] parameter.
Components wrapped in memo() or class components with shouldComponentUpdate are recommended to prevent unnecessary re-renders and reduce noise in tracing data.